@@ -170,6 +170,7 @@ namespace dxvk {
170
170
// We still need to clear caches even if the scene wasn't rendered
171
171
m_bufferCache.clear ();
172
172
m_surfaceMaterialCache.clear ();
173
+ m_preCreationSurfaceMaterialMap.clear ();
173
174
m_surfaceMaterialExtensionCache.clear ();
174
175
m_volumeMaterialCache.clear ();
175
176
@@ -488,6 +489,9 @@ namespace dxvk {
488
489
m_uniqueObjectSearchDistance = RtxOptions::uniqueObjectDistance ();
489
490
m_drawCallCache.rebuildSpatialMaps ();
490
491
}
492
+
493
+ // Not currently safe to cache these across frames (due to texture indices and rtx options potentially changing)
494
+ m_preCreationSurfaceMaterialMap.clear ();
491
495
}
492
496
493
497
void SceneManager::onFrameEndNoRTX () {
@@ -517,10 +521,7 @@ namespace dxvk {
517
521
if (pFogReplacement->getType () != MaterialDataType::Translucent) {
518
522
Logger::warn (str::format (" Fog replacement materials must be translucent. Ignoring material for " , std::hex, m_fog.getHash ()));
519
523
} else {
520
- std::optional<RtSurfaceMaterial> surfaceMaterial {};
521
-
522
- createSurfaceMaterial (ctx, surfaceMaterial, *pFogReplacement, input);
523
- m_startInMediumMaterialIndex = m_surfaceMaterialCache.track (*surfaceMaterial);
524
+ createSurfaceMaterial (ctx, *pFogReplacement, input);
524
525
}
525
526
} else if (m_fog.mode == D3DFOG_NONE) {
526
527
// render the first unreplaced fog.
@@ -901,17 +902,8 @@ namespace dxvk {
901
902
902
903
// Note: Use either the specified override Material Data or the original draw calls state's Material Data to create a Surface Material if no override is specified
903
904
const auto renderMaterialDataType = renderMaterialData.getType ();
904
- std::optional<RtSurfaceMaterial> surfaceMaterial{};
905
-
906
- createSurfaceMaterial (ctx, surfaceMaterial, renderMaterialData, drawCallState);
907
-
908
- assert (surfaceMaterial.has_value ());
909
- assert (surfaceMaterial->validate ());
910
-
911
- // Cache this
912
- m_surfaceMaterialCache.track (*surfaceMaterial);
913
-
914
- RtInstance* instance = m_instanceManager.processSceneObject (m_cameraManager, m_rayPortalManager, *pBlas, drawCallState, renderMaterialData, *surfaceMaterial);
905
+ const RtSurfaceMaterial& surfaceMaterial = createSurfaceMaterial (ctx, renderMaterialData, drawCallState);
906
+ RtInstance* instance = m_instanceManager.processSceneObject (m_cameraManager, m_rayPortalManager, *pBlas, drawCallState, renderMaterialData, surfaceMaterial);
915
907
916
908
// Check if a light should be created for this Material
917
909
if (instance && RtxOptions::Get ()->shouldConvertToLight (drawCallState.getMaterialData ().getHash ())) {
@@ -947,10 +939,9 @@ namespace dxvk {
947
939
return instance ? instance->getId () : UINT64_MAX;
948
940
}
949
941
950
- void SceneManager::createSurfaceMaterial ( Rc<DxvkContext> ctx,
951
- std::optional<RtSurfaceMaterial>& surfaceMaterial,
952
- const MaterialData& renderMaterialData,
953
- const DrawCallState& drawCallState) {
942
+ const RtSurfaceMaterial& SceneManager::createSurfaceMaterial ( Rc<DxvkContext> ctx,
943
+ const MaterialData& renderMaterialData,
944
+ const DrawCallState& drawCallState) {
954
945
ScopedCpuProfileZone ();
955
946
const bool hasTexcoords = drawCallState.hasTextureCoordinates ();
956
947
const auto renderMaterialDataType = renderMaterialData.getType ();
@@ -963,7 +954,7 @@ namespace dxvk {
963
954
Rc<DxvkSampler> sampler = originalSampler;
964
955
// If the original sampler if valid and the new rendering material is not legacy type
965
956
// go ahead with patching and maybe merging the sampler states
966
- if (originalSampler != nullptr && renderMaterialDataType != MaterialDataType::Legacy) {
957
+ if (originalSampler != nullptr && renderMaterialDataType != MaterialDataType::Legacy) {
967
958
DxvkSamplerCreateInfo samplerInfo = originalSampler->info (); // Use sampler create info struct as convenience
968
959
renderMaterialData.populateSamplerInfo (samplerInfo);
969
960
@@ -972,6 +963,26 @@ namespace dxvk {
972
963
samplerInfo.borderColor );
973
964
}
974
965
uint32_t samplerIndex = trackSampler (sampler);
966
+ uint32_t samplerIndex2 = UINT32_MAX;
967
+ if (renderMaterialDataType == MaterialDataType::RayPortal) {
968
+ samplerIndex2 = trackSampler (drawCallState.getMaterialData ().getSampler2 ());
969
+ }
970
+
971
+ XXH64_hash_t preCreationHash = renderMaterialData.getHash ();
972
+ if (renderMaterialDataType == MaterialDataType::Legacy) {
973
+ preCreationHash = XXH64 (&renderMaterialData.getLegacyMaterialData (), sizeof (LegacyMaterialData), preCreationHash);
974
+ }
975
+ preCreationHash = XXH64 (&samplerIndex, sizeof (samplerIndex), preCreationHash);
976
+ preCreationHash = XXH64 (&samplerIndex2, sizeof (samplerIndex2), preCreationHash);
977
+ preCreationHash = XXH64 (&hasTexcoords, sizeof (hasTexcoords), preCreationHash);
978
+ preCreationHash = XXH64 (&drawCallState.isUsingRaytracedRenderTarget , sizeof (drawCallState.isUsingRaytracedRenderTarget ), preCreationHash);
979
+
980
+ auto iter = m_preCreationSurfaceMaterialMap.find (preCreationHash);
981
+ if (iter != m_preCreationSurfaceMaterialMap.end ()) {
982
+ return m_surfaceMaterialCache.at (iter->second );
983
+ }
984
+
985
+ std::optional<RtSurfaceMaterial> surfaceMaterial;
975
986
976
987
if (renderMaterialDataType == MaterialDataType::Legacy || renderMaterialDataType == MaterialDataType::Opaque || drawCallState.isUsingRaytracedRenderTarget ) {
977
988
uint32_t albedoOpacityTextureIndex = kSurfaceMaterialInvalidTextureIndex ;
@@ -1168,8 +1179,6 @@ namespace dxvk {
1168
1179
uint32_t maskTextureIndex2 = kSurfaceMaterialInvalidTextureIndex ;
1169
1180
trackTexture (ctx, rayPortalMaterialData.getMaskTexture2 (), maskTextureIndex2, hasTexcoords, false );
1170
1181
1171
- uint32_t samplerIndex2 = trackSampler (drawCallState.getMaterialData ().getSampler2 ());
1172
-
1173
1182
uint8_t rayPortalIndex = rayPortalMaterialData.getRayPortalIndex ();
1174
1183
float rotationSpeed = rayPortalMaterialData.getRotationSpeed ();
1175
1184
bool enableEmissive = rayPortalMaterialData.getEnableEmission ();
@@ -1182,6 +1191,14 @@ namespace dxvk {
1182
1191
1183
1192
surfaceMaterial.emplace (rayPortalSurfaceMaterial);
1184
1193
}
1194
+
1195
+ assert (surfaceMaterial.has_value ());
1196
+ assert (surfaceMaterial->validate ());
1197
+
1198
+ // Cache this
1199
+ const uint32_t index = m_surfaceMaterialCache.track (*surfaceMaterial);
1200
+ m_preCreationSurfaceMaterialMap[preCreationHash] = index ;
1201
+ return m_surfaceMaterialCache.at (index );
1185
1202
}
1186
1203
1187
1204
std::optional<XXH64_hash_t> SceneManager::findLegacyTextureHashByObjectPickingValue (uint32_t objectPickingValue) {
0 commit comments