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

Metal: avoid redundant scissor rect state changes #8207

Merged
merged 2 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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 filament/backend/src/metal/MetalContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ struct MetalContext {
CullModeStateTracker cullModeState;
WindingStateTracker windingState;
DepthClampStateTracker depthClampState;
ScissorRectStateTracker scissorRectState;
Handle<HwRenderPrimitive> currentRenderPrimitive;

// State caches.
Expand Down
7 changes: 6 additions & 1 deletion filament/backend/src/metal/MetalDriver.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1227,6 +1227,7 @@
mContext->depthStencilState.invalidate();
mContext->cullModeState.invalidate();
mContext->windingState.invalidate();
mContext->scissorRectState.invalidate();
mContext->currentPolygonOffset = {0.0f, 0.0f};

mContext->finalizedDescriptorSets.clear();
Expand Down Expand Up @@ -1953,7 +1954,11 @@
.height = static_cast<NSUInteger>(bottom - top)
};

[mContext->currentRenderPassEncoder setScissorRect:scissorRect];
auto& srs = mContext->scissorRectState;
srs.updateState(scissorRect);
if (srs.stateChanged()) {
[mContext->currentRenderPassEncoder setScissorRect:scissorRect];
}
}

void MetalDriver::beginTimerQuery(Handle<HwTimerQuery> tqh) {
Expand Down
16 changes: 12 additions & 4 deletions filament/backend/src/metal/MetalState.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,17 +204,16 @@ class StateCache {
// Different kinds of state, like pipeline state, uniform buffer state, etc., are passed to the
// current Metal command encoder and persist throughout the lifetime of the encoder (a frame).
// StateTracker is used to prevent calling redundant state change methods.
template<typename StateType>
template <typename StateType, typename StateEqual = std::equal_to<StateType>>
class StateTracker {

public:

// Call to force the state to dirty at the beginning of each frame, as all state must be
// re-bound.
void invalidate() noexcept { mStateDirty = true; }

void updateState(const StateType& newState) noexcept {
if (mCurrentState != newState) {
if (!StateEqual()(mCurrentState, newState)) {
mCurrentState = newState;
mStateDirty = true;
}
Expand All @@ -235,7 +234,6 @@ class StateTracker {

bool mStateDirty = true;
StateType mCurrentState = {};

};

// Pipeline state
Expand Down Expand Up @@ -343,6 +341,16 @@ using DepthStencilStateTracker = StateTracker<DepthStencilState>;
using DepthStencilStateCache = StateCache<DepthStencilState, id<MTLDepthStencilState>,
DepthStateCreator>;

struct MtlScissorRectEqual {
bool operator()(MTLScissorRect lhs, MTLScissorRect rhs) const {
bejado marked this conversation as resolved.
Show resolved Hide resolved
return lhs.height == rhs.height &&
lhs.width == rhs.width &&
lhs.x == rhs.x &&
lhs.y == rhs.y;
}
};
using ScissorRectStateTracker = StateTracker<MTLScissorRect, MtlScissorRectEqual>;

// Uniform buffers

class MetalBufferObject;
Expand Down
Loading