diff options
| author | git perforce import user <a@b> | 2016-10-25 12:29:14 -0600 |
|---|---|---|
| committer | Sheikh Dawood Abdul Ajees <Sheikh Dawood Abdul Ajees> | 2016-10-25 18:56:37 -0500 |
| commit | 3dfe2108cfab31ba3ee5527e217d0d8e99a51162 (patch) | |
| tree | fa6485c169e50d7415a651bf838f5bcd0fd3bfbd /APEX_1.4/common/include/RenderAPIIntl.h | |
| download | physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.tar.xz physx-3.4-3dfe2108cfab31ba3ee5527e217d0d8e99a51162.zip | |
Initial commit:
PhysX 3.4.0 Update @ 21294896
APEX 1.4.0 Update @ 21275617
[CL 21300167]
Diffstat (limited to 'APEX_1.4/common/include/RenderAPIIntl.h')
| -rw-r--r-- | APEX_1.4/common/include/RenderAPIIntl.h | 515 |
1 files changed, 515 insertions, 0 deletions
diff --git a/APEX_1.4/common/include/RenderAPIIntl.h b/APEX_1.4/common/include/RenderAPIIntl.h new file mode 100644 index 00000000..481712be --- /dev/null +++ b/APEX_1.4/common/include/RenderAPIIntl.h @@ -0,0 +1,515 @@ +/* + * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved. + * + * NVIDIA CORPORATION and its licensors retain all intellectual property + * and proprietary rights in and to this software, related documentation + * and any modifications thereto. Any use, reproduction, disclosure or + * distribution of this software and related documentation without an express + * license agreement from NVIDIA CORPORATION is strictly prohibited. + */ + + +#ifndef RENDER_API_INTL_H +#define RENDER_API_INTL_H + +#include "PsArray.h" +#include "PsMutex.h" +#include "UserRenderCallback.h" +#if APEX_CUDA_SUPPORT +#include <cuda.h> +#endif + +namespace nvidia +{ +namespace apex +{ + +struct RenderEntityMapStateIntl +{ + enum Enum + { + UNMAPPED = 0, + PENDING_MAP, + MAPPED, + PENDING_UNMAP + }; +}; + +class RenderStorageStateIntl +{ +public: + PX_INLINE bool isMapped() const { return (mMapFlags & MAPPED) != 0; } + + virtual bool map(UserRenderStorage* renderStorage, RenderMapType::Enum mapType) = 0; + virtual void unmap(UserRenderStorage* renderStorage) = 0; + +#if APEX_CUDA_SUPPORT + PX_INLINE bool isCudaMapped() const { return (mMapFlags & CUDA_MAPPED) != 0; } + PX_INLINE void setCudaMapped() { mMapFlags |= CUDA_MAPPED; } + PX_INLINE void resetCudaMapped() { mMapFlags &= ~CUDA_MAPPED; } + + virtual CUgraphicsResource getCudaHandle(UserRenderStorage* renderStorage) = 0; + virtual bool getCudaMapppedResult(UserRenderStorage* renderStorage) = 0; + + PX_INLINE bool checkCudaHandle() const { return mInteropHandle != NULL; } + PX_INLINE void resetCudaHandle() { mInteropHandle = NULL; } +#endif + +protected: + RenderStorageStateIntl() + : mMapFlags(0) +#if APEX_CUDA_SUPPORT + , mInteropHandle(NULL) +#endif + { + } + + enum MapFlag + { + MAPPED = 0x01, +#if APEX_CUDA_SUPPORT + CUDA_MAPPED = 0x02, +#endif + }; + uint32_t mMapFlags; + +#if APEX_CUDA_SUPPORT + CUgraphicsResource mInteropHandle; +#endif +}; + +class RenderBufferStateIntl : public RenderStorageStateIntl +{ +public: + RenderBufferStateIntl() + : mMappedPtr(NULL) +#if APEX_CUDA_SUPPORT + , mMappedCudaPtr(NULL) +#endif + , mMapOffset(0) + , mMapSize(SIZE_MAX) + { + } + + PX_INLINE void* getMappedPtr() const + { + return mMappedPtr; + } + + PX_INLINE void setMapRange(size_t offset, size_t size) + { + mMapOffset = offset; + mMapSize = size; + } + + virtual bool map(UserRenderStorage* renderStorage, RenderMapType::Enum mapType) + { + if ((mMapFlags & MAPPED) == 0) + { + PX_ASSERT(renderStorage->getType() == UserRenderStorage::BUFFER); + UserRenderBuffer* renderBuffer = static_cast<UserRenderBuffer*>(renderStorage); + mMappedPtr = renderBuffer->map(mapType, mMapOffset, mMapSize); + if (mMappedPtr != NULL) + { + mMapFlags += MAPPED; + } + } + return (mMapFlags & MAPPED) != 0; + } + virtual void unmap(UserRenderStorage* renderStorage) + { + if ((mMapFlags & MAPPED) != 0) + { + PX_ASSERT(renderStorage->getType() == UserRenderStorage::BUFFER); + UserRenderBuffer* renderBuffer = static_cast<UserRenderBuffer*>(renderStorage); + renderBuffer->unmap(); + mMappedPtr = NULL; + mMapFlags -= MAPPED; + //reset map range + mMapOffset = 0; + mMapSize = SIZE_MAX; + } + } + +#if APEX_CUDA_SUPPORT + PX_INLINE CUdeviceptr getMappedCudaPtr() const + { + return mMappedCudaPtr; + } + + virtual CUgraphicsResource getCudaHandle(UserRenderStorage* renderStorage) + { + if (mInteropHandle == NULL) + { + PX_ASSERT(renderStorage->getType() == UserRenderStorage::BUFFER); + UserRenderBuffer* renderBuffer = static_cast<UserRenderBuffer*>(renderStorage); + renderBuffer->getCUDAgraphicsResource(mInteropHandle); + } + return mInteropHandle; + } + + virtual bool getCudaMapppedResult(UserRenderStorage* renderStorage) + { + PX_UNUSED(renderStorage); + if (mInteropHandle != NULL) + { + size_t size = 0; + if (cuGraphicsResourceGetMappedPointer(&mMappedCudaPtr, &size, mInteropHandle) == CUDA_SUCCESS) + { + return true; + } + mMappedCudaPtr = NULL; + } + return false; + } +#endif + +private: + void* mMappedPtr; +#if APEX_CUDA_SUPPORT + CUdeviceptr mMappedCudaPtr; +#endif + size_t mMapOffset; + size_t mMapSize; +}; + +class RenderSurfaceStateIntl : public RenderStorageStateIntl +{ +public: + RenderSurfaceStateIntl() +#if APEX_CUDA_SUPPORT + : mMappedCudaArray(NULL) +#endif + { + } + + PX_INLINE const UserRenderSurface::MappedInfo& getMappedInfo() const + { + return mMappedInfo; + } + + virtual bool map(UserRenderStorage* renderStorage, RenderMapType::Enum mapType) + { + if ((mMapFlags & MAPPED) == 0) + { + PX_ASSERT(renderStorage->getType() == UserRenderStorage::SURFACE); + UserRenderSurface* renderSurface = static_cast<UserRenderSurface*>(renderStorage); + if (renderSurface->map(mapType, mMappedInfo)) + { + mMapFlags += MAPPED; + } + } + return (mMapFlags & MAPPED) != 0; + } + virtual void unmap(UserRenderStorage* renderStorage) + { + if ((mMapFlags & MAPPED) != 0) + { + PX_ASSERT(renderStorage->getType() == UserRenderStorage::SURFACE); + UserRenderSurface* renderSurface = static_cast<UserRenderSurface*>(renderStorage); + renderSurface->unmap(); + mMapFlags -= MAPPED; + } + } +#if APEX_CUDA_SUPPORT + PX_INLINE CUarray getMappedCudaArray() const + { + return mMappedCudaArray; + } + + virtual CUgraphicsResource getCudaHandle(UserRenderStorage* renderStorage) + { + if (mInteropHandle == NULL) + { + PX_ASSERT(renderStorage->getType() == UserRenderStorage::SURFACE); + UserRenderSurface* renderSurface = static_cast<UserRenderSurface*>(renderStorage); + renderSurface->getCUDAgraphicsResource(mInteropHandle); + } + return mInteropHandle; + } + + virtual bool getCudaMapppedResult(UserRenderStorage* renderStorage) + { + PX_UNUSED(renderStorage); + if (mInteropHandle != NULL) + { + //TODO: cuGraphicsSubResourceGetMappedArray arrayIndex & mipLevel??? + if (cuGraphicsSubResourceGetMappedArray(&mMappedCudaArray, mInteropHandle, 0, 0) == CUDA_SUCCESS) + { + return true; + } + mMappedCudaArray = NULL; + } + return false; + } +#endif + +private: + UserRenderSurface::MappedInfo mMappedInfo; +#if APEX_CUDA_SUPPORT + CUarray mMappedCudaArray; +#endif +}; + +class RenderEntityIntl : public UserAllocated +{ +public: + virtual ~RenderEntityIntl() { PX_ASSERT(mRefCount == 0); } + + virtual void free() = 0; + + + virtual void map() = 0; + virtual void unmap() = 0; + +#if APEX_CUDA_SUPPORT + virtual void fillMapUnmapArraysForInterop(nvidia::Array<CUgraphicsResource> &toMapArray, nvidia::Array<CUgraphicsResource> &toUnmapArray) = 0; + virtual void mapBufferResultsForInterop(bool mapSuccess, bool unmapSuccess) = 0; +#endif + + // + virtual void release() + { + bool triggerDelete = false; + mRefCountLock.lock(); + if (mRefCount > 0) + { + triggerDelete = (--mRefCount) == 0; + } + mRefCountLock.unlock(); + if (triggerDelete) + { + destroy(); + } + } + + // Returns this if successful, NULL otherwise + RenderEntityIntl* incrementReferenceCount() + { + RenderEntityIntl* returnValue = NULL; + mRefCountLock.lock(); + if (mRefCount > 0) + { + ++mRefCount; + returnValue = this; + } + mRefCountLock.unlock(); + return returnValue; + } + + PX_INLINE int32_t getReferenceCount() const + { + return mRefCount; + } + +protected: + RenderEntityIntl() + : mRefCount(1) // Ref count initialized to 1, assuming that whoever calls this constructor will store a reference + { + } + + virtual void destroy() + { + PX_DELETE(this); + } + + volatile int32_t mRefCount; + physx::shdfnd::Mutex mRefCountLock; + + +private: + RenderEntityIntl& operator=(const RenderEntityIntl&); +}; + +template <typename Impl, typename Base> +class RenderEntityIntlImpl : public Base +{ +protected: + PX_INLINE const Impl* getImpl() const { return static_cast<const Impl*>(this); } + PX_INLINE Impl* getImpl() { return static_cast<Impl*>(this); } + +public: + virtual ~RenderEntityIntlImpl() + { + getImpl()->freeAllRenderStorage(); + } + + + virtual void free() + { + getImpl()->freeAllRenderStorage(); + mMapState = RenderEntityMapStateIntl::UNMAPPED; + } + + virtual void map() + { + if (mMapState == RenderEntityMapStateIntl::UNMAPPED) + { + if (mInteropFlags == RenderInteropFlags::CUDA_INTEROP) + { + mMapState = RenderEntityMapStateIntl::PENDING_MAP; + return; + } + + bool result = false; + if (getImpl()->getRenderStorageCount() > 0) + { + //map render resources + result = true; + for (uint32_t i = 0; result && i < getImpl()->getRenderStorageCount(); ++i) + { + UserRenderStorage* renderStorage; + RenderInteropFlags::Enum interopFlags; + RenderStorageStateIntl& renderStorageState = getImpl()->getRenderStorage(i, renderStorage, interopFlags); + if (renderStorage) + { + getImpl()->onMapRenderStorage(i); + result &= renderStorageState.map(renderStorage, RenderMapType::MAP_WRITE_DISCARD); + } + } + if (!result) + { + //unmap in case of failure + unmapRenderResources(); + } + } + if (result) + { + mMapState = RenderEntityMapStateIntl::MAPPED; + } + } + } + + virtual void unmap() + { + if (mMapState == RenderEntityMapStateIntl::MAPPED) + { + if (mInteropFlags == RenderInteropFlags::CUDA_INTEROP) + { + mMapState = RenderEntityMapStateIntl::PENDING_UNMAP; + return; + } + + unmapRenderResources(); + + mMapState = RenderEntityMapStateIntl::UNMAPPED; + } + } + +#if APEX_CUDA_SUPPORT + virtual void fillMapUnmapArraysForInterop(physx::Array<CUgraphicsResource> &toMapArray, physx::Array<CUgraphicsResource> &toUnmapArray) + { + if (mMapState == RenderEntityMapStateIntl::PENDING_MAP || mMapState == RenderEntityMapStateIntl::PENDING_UNMAP) + { + for (uint32_t i = 0; i < getImpl()->getRenderStorageCount(); ++i) + { + UserRenderStorage* renderStorage; + RenderInteropFlags::Enum interopFlags; + RenderStorageStateIntl& renderStorageState = getImpl()->getRenderStorage(i, renderStorage, interopFlags); + if (renderStorage && interopFlags == RenderInteropFlags::CUDA_INTEROP) + { + CUgraphicsResource interopHandle = renderStorageState.getCudaHandle(renderStorage); + if (interopHandle != NULL) + { + if (mMapState == RenderEntityMapStateIntl::PENDING_MAP && !renderStorageState.isCudaMapped()) + { + toMapArray.pushBack(interopHandle); + } + if (mMapState == RenderEntityMapStateIntl::PENDING_UNMAP && renderStorageState.isCudaMapped()) + { + toUnmapArray.pushBack(interopHandle); + } + } + } + } + } + } + + virtual void mapBufferResultsForInterop(bool mapSuccess, bool unmapSuccess) + { + PX_UNUSED(unmapSuccess); + if (mMapState == RenderEntityMapStateIntl::PENDING_MAP || mMapState == RenderEntityMapStateIntl::PENDING_UNMAP) + { + bool result = false; + if (getImpl()->getRenderStorageCount() > 0) + { + //map render resources + result = true; + for (uint32_t i = 0; i < getImpl()->getRenderStorageCount(); ++i) + { + UserRenderStorage* renderStorage; + RenderInteropFlags::Enum interopFlags; + RenderStorageStateIntl& renderStorageState = getImpl()->getRenderStorage(i, renderStorage, interopFlags); + if (renderStorage) + { + bool mappedResult = false; + if (renderStorageState.checkCudaHandle()) + { + if (mMapState == RenderEntityMapStateIntl::PENDING_MAP && mapSuccess) + { + renderStorageState.setCudaMapped(); + mappedResult = renderStorageState.getCudaMapppedResult(renderStorage); + } + if (mMapState == RenderEntityMapStateIntl::PENDING_UNMAP && unmapSuccess) + { + renderStorageState.resetCudaMapped(); + } + renderStorageState.resetCudaHandle(); + } + if (mMapState == RenderEntityMapStateIntl::PENDING_MAP && !mappedResult) + { + //fall back to CPU mapping + if (result) + { + getImpl()->onMapRenderStorage(i); + result &= renderStorageState.map(renderStorage, RenderMapType::MAP_WRITE_DISCARD); + } + } + } + } + } + + if (result && mMapState == RenderEntityMapStateIntl::PENDING_MAP) + { + mMapState = RenderEntityMapStateIntl::MAPPED; + } + else + { + unmapRenderResources(); + + mMapState = RenderEntityMapStateIntl::UNMAPPED; + } + } + } +#endif + +protected: + RenderEntityIntlImpl(RenderInteropFlags::Enum interopFlags) + : mInteropFlags(interopFlags) + , mMapState(RenderEntityMapStateIntl::UNMAPPED) + { + } + + void unmapRenderResources() + { + for (uint32_t i = 0; i < getImpl()->getRenderStorageCount(); ++i) + { + UserRenderStorage* renderStorage; + RenderInteropFlags::Enum interopFlags; + RenderStorageStateIntl& renderStorageState = getImpl()->getRenderStorage(i, renderStorage, interopFlags); + if (renderStorage) + { + renderStorageState.unmap(renderStorage); + } + } + } + + RenderInteropFlags::Enum mInteropFlags; + RenderEntityMapStateIntl::Enum mMapState; +}; + + +} +} // end namespace nvidia::apex + +#endif // #ifndef RENDER_API_INTL_H |