Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MAYA-113944 If USD reports that the topology is dirty compare the #2143

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/mayaUsd/render/vp2RenderDelegate/draw_item.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class HdVP2DrawItem final : public HdDrawItem

//! Render item index buffer - use when updating data
std::unique_ptr<MHWRender::MIndexBuffer> _indexBuffer;
bool _indexBufferValid { false };
//! Bounding box of the render item.
MBoundingBox _boundingBox;
//! World matrix of the render item.
Expand Down
76 changes: 59 additions & 17 deletions lib/mayaUsd/render/vp2RenderDelegate/mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -528,15 +528,25 @@ void HdVP2Mesh::_PrepareSharedVertexBuffers(
if (computeCPUNormals) {
// note: normals gets dirty when points are marked as dirty,
// at change tracker.
Hd_VertexAdjacencySharedPtr adjacency(new Hd_VertexAdjacency());
HdBufferSourceSharedPtr adjacencyComputation
= adjacency->GetSharedAdjacencyBuilderComputation(&_meshSharedData->_topology);
adjacencyComputation->Resolve();
if (!_meshSharedData->_adjacency) {
_meshSharedData->_adjacency.reset(new Hd_VertexAdjacency());

HdBufferSourceSharedPtr adjacencyComputation
= _meshSharedData->_adjacency->GetSharedAdjacencyBuilderComputation(
&_meshSharedData->_topology);
MProfilingScope profilingScope(
HdVP2RenderDelegate::sProfilerCategory,
MProfiler::kColorC_L2,
_rprimId.asChar(),
"HdVP2Mesh::computeAdjacency");

adjacencyComputation->Resolve();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This call to resolve is slow, so save the result and only re-do it if the topology actually changes.

}

// Only the points referenced by the topology are used to compute
// smooth normals.
VtValue normals(Hd_SmoothNormals::ComputeSmoothNormals(
adjacency.get(),
_meshSharedData->_adjacency.get(),
_points(_meshSharedData->_primvarInfo).size(),
_points(_meshSharedData->_primvarInfo).cdata()));

Expand Down Expand Up @@ -919,7 +929,21 @@ void HdVP2Mesh::Sync(
MProfiler::kColorC_L2,
_rprimId.asChar(),
"HdVP2Mesh::GetMeshTopology");
_meshSharedData->_topology = GetMeshTopology(delegate);
HdMeshTopology newTopology = GetMeshTopology(delegate);

// Test to see if the topology actually changed. If not, we don't have to do anything!
// Don't test IsTopologyDirty anywhere below this because it is not accurate. Instead
// using the _indexBufferValid flag on render item data.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need the separate flag because we've already lost dirty information by the time sync is called. In propagate dirty bits the old topology dirty flag saved the the render item was overwritten. If that item hasn't been getting updated (because it's in a repr that is not currently displayed) then we don't know if there was a ligitimate topology change before this frame that still needs to be handled for that item.

For that reason I need the separate _indexBufferValid flag per render item.

if (!(newTopology == _meshSharedData->_topology)) {
_meshSharedData->_topology = newTopology;
_meshSharedData->_adjacency.reset();
_meshSharedData->_renderingTopology = HdMeshTopology();

auto setIndexBufferDirty = [](HdVP2DrawItem::RenderItemData& renderItemData) {
renderItemData._indexBufferValid = false;
};
_ForEachRenderItem(setIndexBufferDirty);
}
}

// subscribe to material updates from the new geom subset materials
Expand Down Expand Up @@ -1030,7 +1054,7 @@ void HdVP2Mesh::Sync(
_UpdatePrimvarSources(delegate, *dirtyBits, _meshSharedData->_allRequiredPrimvars);
}

if (HdChangeTracker::IsTopologyDirty(*dirtyBits, id)) {
if (_meshSharedData->_renderingTopology == HdMeshTopology()) {
MProfilingScope profilingScope(
HdVP2RenderDelegate::sProfilerCategory,
MProfiler::kColorC_L2,
Expand Down Expand Up @@ -1752,16 +1776,16 @@ void HdVP2Mesh::_UpdateDrawItem(
#endif

// Prepare index buffer.
if (requiresIndexUpdate && (itemDirtyBits & HdChangeTracker::DirtyTopology)) {
if (requiresIndexUpdate && !renderItemData._indexBufferValid) {
const HdMeshTopology& topologyToUse = _meshSharedData->_renderingTopology;

MProfilingScope profilingScope(
HdVP2RenderDelegate::sProfilerCategory,
MProfiler::kColorC_L2,
_rprimId.asChar(),
"HdVP2Mesh prepare index buffer");

if (desc.geomStyle == HdMeshGeomStyleHull) {
MProfilingScope profilingScope(
HdVP2RenderDelegate::sProfilerCategory,
MProfiler::kColorC_L2,
_rprimId.asChar(),
"HdVP2Mesh prepare index buffer");

// _trianglesFaceVertexIndices has the full triangulation calculated in
// _updateRepr. Find the triangles which represent faces in the matching
// geom subset and add those triangles to the index buffer for renderItem.
Expand Down Expand Up @@ -1851,6 +1875,7 @@ void HdVP2Mesh::_UpdateDrawItem(
: nullptr;
_FillEdgeIndices(stateToCommit._indexBufferData, topologyToUse);
}
renderItemData._indexBufferValid = true;
}

#ifdef HDVP2_ENABLE_GPU_COMPUTE
Expand Down Expand Up @@ -2472,6 +2497,18 @@ void HdVP2Mesh::_UpdateDrawItem(
}

void HdVP2Mesh::_HideAllDrawItems(const TfToken& reprToken)
{
auto hideDrawItem = [this](HdVP2DrawItem::RenderItemData& renderItemData) {
renderItemData._enabled = false;
_delegate->GetVP2ResourceRegistry().EnqueueCommit(
[&]() { renderItemData._renderItem->enable(false); });
};

_ForEachRenderItemInRepr(reprToken, hideDrawItem);
}

template <typename Func>
void HdVP2Mesh::_ForEachRenderItemInRepr(const TfToken& reprToken, Func func)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this could more to the parent class once the clean up gets merged.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. I moved this function to the parent class so this will have to be propely merged.

{
HdReprSharedPtr const& curRepr = _GetRepr(reprToken);
if (!curRepr) {
Expand All @@ -2493,13 +2530,18 @@ void HdVP2Mesh::_HideAllDrawItems(const TfToken& reprToken)
continue;

for (auto& renderItemData : drawItem->GetRenderItems()) {
renderItemData._enabled = false;
_delegate->GetVP2ResourceRegistry().EnqueueCommit(
[&]() { renderItemData._renderItem->enable(false); });
func(renderItemData);
}
}
}

template <typename Func> void HdVP2Mesh::_ForEachRenderItem(Func func)
{
for (const std::pair<TfToken, HdReprSharedPtr>& pair : _reprs) {
_ForEachRenderItemInRepr(pair.first, func);
}
}

#ifdef HDVP2_ENABLE_GPU_COMPUTE
/*! \brief Save topology information for later GPGPU evaluation

Expand Down
8 changes: 8 additions & 0 deletions lib/mayaUsd/render/vp2RenderDelegate/mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <mayaUsd/render/vp2RenderDelegate/proxyRenderDelegate.h>

#include <pxr/imaging/hd/mesh.h>
#include <pxr/imaging/hd/vertexAdjacency.h>
#include <pxr/pxr.h>

#include <maya/MHWGeometry.h>
Expand All @@ -48,6 +49,9 @@ struct HdVP2MeshSharedData
//! copy.
HdMeshTopology _topology;

//! Adjacency based off of _topology
Hd_VertexAdjacencySharedPtr _adjacency;

//! The rendering topology is to create unshared or sorted vertice layout
//! for efficient GPU rendering.
HdMeshTopology _renderingTopology;
Expand Down Expand Up @@ -145,6 +149,10 @@ class HdVP2Mesh final : public HdMesh

void _HideAllDrawItems(const TfToken& reprToken);

template <typename Func> void _ForEachRenderItemInRepr(const TfToken& reprToken, Func func);

template <typename Func> void _ForEachRenderItem(Func func);

void _UpdatePrimvarSources(
HdSceneDelegate* sceneDelegate,
HdDirtyBits dirtyBits,
Expand Down