Revision control

Copy as Markdown

// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
// SPDX-FileCopyrightText: Copyright (c) 2008-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
#ifndef PXC_NP_CACHE_H
#define PXC_NP_CACHE_H
#include "foundation/PxMemory.h"
#include "foundation/PxIntrinsics.h"
#include "foundation/PxPool.h"
#include "foundation/PxPreprocessor.h"
#include "foundation/PxUtilities.h"
#include "PxcNpCacheStreamPair.h"
#include "GuContactMethodImpl.h"
namespace physx
{
PX_FORCE_INLINE void PxcNpCacheReserve(PxcNpCacheStreamPair& streams, Gu::Cache& cache, PxU32 bytes)
{
bool sizeTooLarge;
PxU8* ls = streams.reserve(bytes, sizeTooLarge);
cache.mCachedData = ls;
if(sizeTooLarge)
{
// PT: TODO: consider changing the error message, it will silently become obsolete if we change the value of PxcNpMemBlock::SIZE.
// On the other hand the PxSceneDesc::maxNbContactDataBlocks also hardcodes "16K data blocks" so this isn't urgent.
PX_WARN_ONCE(
"Attempting to allocate more than 16K of contact data for a single contact pair in narrowphase. "
"Either accept dropped contacts or simplify collision geometry.");
}
else if(ls==NULL)
{
PX_WARN_ONCE(
"Reached limit set by PxSceneDesc::maxNbContactDataBlocks - ran out of buffer space for narrow phase. "
"Either accept dropped contacts or increase buffer size allocated for narrow phase by increasing PxSceneDesc::maxNbContactDataBlocks.");
}
}
template <typename T>
void PxcNpCacheWrite(PxcNpCacheStreamPair& streams,
Gu::Cache& cache,
const T& payload,
PxU32 bytes,
const PxU8* data)
{
PxU8* ls = PxcNpCacheWriteInitiate(streams, cache, payload, bytes);
if (ls == NULL)
return;
PxcNpCacheWriteFinalize(ls, payload, bytes, data);
}
template <typename T>
PxU8* PxcNpCacheWriteInitiate(PxcNpCacheStreamPair& streams, Gu::Cache& cache, const T& payload, PxU32 bytes)
{
const PxU32 payloadSize = (sizeof(payload)+3)&~3;
cache.mCachedSize = PxTo16((payloadSize + 4 + bytes + 0xF)&~0xF);
PxcNpCacheReserve(streams, cache, cache.mCachedSize);
return cache.mCachedData;
}
template <typename T>
PX_FORCE_INLINE void PxcNpCacheWriteFinalize(PxU8* ls, const T& payload, PxU32 bytes, const PxU8* data)
{
const PxU32 payloadSize = (sizeof(payload)+3)&~3;
*reinterpret_cast<T*>(ls) = payload;
*reinterpret_cast<PxU32*>(ls+payloadSize) = bytes;
if(data)
PxMemCopy(ls+payloadSize+sizeof(PxU32), data, bytes);
}
template <typename T>
PX_FORCE_INLINE PxU8* PxcNpCacheRead(Gu::Cache& cache, T*& payload)
{
PxU8* ls = cache.mCachedData;
payload = reinterpret_cast<T*>(ls);
const PxU32 payloadSize = (sizeof(T)+3)&~3;
return reinterpret_cast<PxU8*>(ls+payloadSize+sizeof(PxU32));
}
template <typename T>
const PxU8* PxcNpCacheRead2(Gu::Cache& cache, T& payload, PxU32& bytes)
{
const PxU8* ls = cache.mCachedData;
if(ls==NULL)
{
bytes = 0;
return NULL;
}
const PxU32 payloadSize = (sizeof(payload)+3)&~3;
payload = *reinterpret_cast<const T*>(ls);
bytes = *reinterpret_cast<const PxU32*>(ls+payloadSize);
PX_ASSERT(cache.mCachedSize == ((payloadSize + 4 + bytes+0xF)&~0xF));
return reinterpret_cast<const PxU8*>(ls+payloadSize+sizeof(PxU32));
}
}
#endif