2121*/
2222#include " rtx_camera_manager.h"
2323
24- #include " rtx_matrix_helpers.h"
25-
2624#include " dxvk_device.h"
2725
2826namespace {
@@ -44,6 +42,7 @@ namespace dxvk {
4442
4543 void CameraManager::onFrameEnd () {
4644 m_lastSetCameraType = CameraType::Unknown;
45+ m_decompositionCache.clear ();
4746 }
4847
4948 CameraType::Enum CameraManager::processCameraData (const DrawCallState& input) {
@@ -75,10 +74,7 @@ namespace dxvk {
7574 }
7675
7776 // Get camera params
78- float fov, aspectRatio, nearPlane, farPlane, shearX, shearY;
79- bool isLHS;
80- bool isReverseZ;
81- decomposeProjection (input.getTransformData ().viewToProjection , aspectRatio, fov, nearPlane, farPlane, shearX, shearY, isLHS, isReverseZ);
77+ DecomposeProjectionParams decomposeProjectionParams = getOrDecomposeProjection (input.getTransformData ().viewToProjection );
8278
8379 // Filter invalid cameras, extreme shearing
8480 static auto isFovValid = [](float fovA) {
@@ -88,7 +84,7 @@ namespace dxvk {
8884 return std::abs (fovA - cameraB.getFov ()) < kFovToleranceRadians ;
8985 };
9086
91- if (std::abs (shearX) > 0 .01f || !isFovValid (fov)) {
87+ if (std::abs (decomposeProjectionParams. shearX ) > 0 .01f || !isFovValid (decomposeProjectionParams. fov )) {
9288 ONCE (Logger::warn (" [RTX] CameraManager: rejected an invalid camera" ));
9389 return input.getCategoryFlags ().test (InstanceCategories::Sky) ? CameraType::Sky : CameraType::Unknown;
9490 }
@@ -117,13 +113,13 @@ namespace dxvk {
117113 cameraType = CameraType::RenderToTexture;
118114 } else if (input.testCategoryFlags (InstanceCategories::Sky)) {
119115 cameraType = CameraType::Sky;
120- } else if (isViewModel (fov, input.maxZ , frameId)) {
116+ } else if (isViewModel (decomposeProjectionParams. fov , input.maxZ , frameId)) {
121117 cameraType = CameraType::ViewModel;
122118 }
123119
124120 // Check fov consistency across frames
125121 if (frameId > 0 ) {
126- if (getCamera (cameraType).isValid (frameId - 1 ) && !areFovsClose (fov, getCamera (cameraType))) {
122+ if (getCamera (cameraType).isValid (frameId - 1 ) && !areFovsClose (decomposeProjectionParams. fov , getCamera (cameraType))) {
127123 ONCE (Logger::warn (" [RTX] CameraManager: FOV of a camera changed between frames" ));
128124 }
129125 }
@@ -148,7 +144,15 @@ namespace dxvk {
148144 }
149145 } else {
150146 isCameraCut = camera.update (
151- frameId, worldToView, viewToProjection, fov, aspectRatio, nearPlane,farPlane, isLHS);
147+ frameId,
148+ worldToView,
149+ viewToProjection,
150+ decomposeProjectionParams.fov ,
151+ decomposeProjectionParams.aspectRatio ,
152+ decomposeProjectionParams.nearPlane ,
153+ decomposeProjectionParams.farPlane ,
154+ decomposeProjectionParams.isLHS
155+ );
152156 }
153157
154158
@@ -173,13 +177,29 @@ namespace dxvk {
173177 void CameraManager::processExternalCamera (CameraType::Enum type,
174178 const Matrix4& worldToView,
175179 const Matrix4& viewToProjection) {
176- float fov, aspectRatio, nearPlane, farPlane, shearX, shearY;
177- bool isLHS;
178- bool isReverseZ;
179- decomposeProjection (viewToProjection, aspectRatio, fov, nearPlane, farPlane, shearX, shearY, isLHS, isReverseZ);
180+ DecomposeProjectionParams decomposeProjectionParams = getOrDecomposeProjection (viewToProjection);
180181
181182 getCamera (type).update (
182183 m_device->getCurrentFrameId (),
183- worldToView, viewToProjection, fov, aspectRatio, nearPlane, farPlane, isLHS);
184+ worldToView,
185+ viewToProjection,
186+ decomposeProjectionParams.fov ,
187+ decomposeProjectionParams.aspectRatio ,
188+ decomposeProjectionParams.nearPlane ,
189+ decomposeProjectionParams.farPlane ,
190+ decomposeProjectionParams.isLHS );
184191 }
192+
193+ DecomposeProjectionParams CameraManager::getOrDecomposeProjection (const Matrix4& viewToProjection) {
194+ XXH64_hash_t projectionHash = XXH64 (&viewToProjection, sizeof (viewToProjection), 0 );
195+ auto iter = m_decompositionCache.find (projectionHash);
196+ if (iter != m_decompositionCache.end ()) {
197+ return iter->second ;
198+ }
199+
200+ DecomposeProjectionParams decomposeProjectionParams;
201+ decomposeProjection (viewToProjection, decomposeProjectionParams);
202+ m_decompositionCache.emplace (projectionHash, decomposeProjectionParams);
203+ return decomposeProjectionParams;
204+ }
185205} // namespace dxvk
0 commit comments