Skip to content

Commit

Permalink
[REMIX-3744] Small optimization to findSimilarInstances that improves…
Browse files Browse the repository at this point in the history
… the exact transform match case.

This separates the check for exact transform from the distance check, and only runs the exact transform check on instances that share the same grid cell (rather than the nearest 2x2x2 patch of grid cells).

The change also fixes the logic slightly - previously, an instance with the same position but a different orientation or scale would be used as soon as it was found - even if a later instance may have a perfect match.
  • Loading branch information
MarkEHenderson committed Nov 26, 2024
1 parent b4ca5f6 commit fd7a965
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 7 deletions.
21 changes: 14 additions & 7 deletions src/dxvk/rtx_render/rtx_instance_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -652,17 +652,24 @@ namespace dxvk {

// Search the BLAS for an instance matching ours
{
const auto adjacentCells = blas.getSpatialMap().getDataNearPos(worldPosition);
for (const std::vector<const RtInstance*>* cellPtr : adjacentCells){
for (const RtInstance* instance : *cellPtr) {
if (instance->m_frameLastUpdated == currentFrameIdx) {
// If the transform is an exact match and the instance has already been touched this frame,
// then this is a second draw call on a single mesh.
// Search for an exact match
const std::vector<const RtInstance*>* matchingCell = blas.getSpatialMap().getDataAtPos(worldPosition);
if (matchingCell != nullptr) {
for (const RtInstance* instance : *matchingCell) {
const Matrix4 instanceTransform = instance->getTransform();
// Note: this may be the second call this frame targetting the same instance.
if (memcmp(&transform, &instanceTransform, sizeof(instanceTransform)) == 0) {
return const_cast<RtInstance*>(instance);
}
} else if (instance->m_materialHash == material.getHash()) {
}
}

// No exact match, so find the closest match in the region
// (need to check a 2x2x2 patch of cells to account for positions close to a border)
const auto adjacentCells = blas.getSpatialMap().getDataNearPos(worldPosition);
for (const std::vector<const RtInstance*>* cellPtr : adjacentCells){
for (const RtInstance* instance : *cellPtr) {
if (instance->m_frameLastUpdated != currentFrameIdx && instance->m_materialHash == material.getHash()) {
// Instance hasn't been touched yet this frame.

const Vector3& prevInstanceWorldPosition = instance->getSpatialCachePosition();
Expand Down
9 changes: 9 additions & 0 deletions src/util/util_spatial_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,15 @@ namespace dxvk {
return *this;
}

// returns the cell closest to `position`
const std::vector<T>* getDataAtPos(const Vector3& position) const {
auto pair = m_cache.find(getCellPos(position));
if ( pair != m_cache.end()) {
return &pair->second;
}
return nullptr;
}

// returns the 8 cells closest to `position`
const std::vector<const std::vector<T>*> getDataNearPos(const Vector3& position) const {
static const std::array kOffsets{
Expand Down

0 comments on commit fd7a965

Please sign in to comment.