aboutsummaryrefslogtreecommitdiff
path: root/NvCloth/src/dx/DxDeviceVector.h
diff options
context:
space:
mode:
Diffstat (limited to 'NvCloth/src/dx/DxDeviceVector.h')
-rw-r--r--NvCloth/src/dx/DxDeviceVector.h388
1 files changed, 388 insertions, 0 deletions
diff --git a/NvCloth/src/dx/DxDeviceVector.h b/NvCloth/src/dx/DxDeviceVector.h
new file mode 100644
index 0000000..d64bd77
--- /dev/null
+++ b/NvCloth/src/dx/DxDeviceVector.h
@@ -0,0 +1,388 @@
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and 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.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved.
+// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
+// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
+
+#pragma once
+
+#include "NvCloth/DxContextManagerCallback.h"
+#include "DxCheckSuccess.h"
+#include "NvCloth/Allocator.h"
+
+namespace nv
+{
+namespace cloth
+{
+
+struct DxBufferFlags
+{
+ D3D11_USAGE mUsage;
+ D3D11_BIND_FLAG mBindFlag;
+ D3D11_RESOURCE_MISC_FLAG mMiscFlag;
+ D3D11_CPU_ACCESS_FLAG mCpuAccessFlag;
+};
+
+inline DxBufferFlags DxDefaultBufferPolicy()
+{
+ DxBufferFlags result = { D3D11_USAGE_DEFAULT,
+ D3D11_BIND_FLAG(D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS),
+ D3D11_RESOURCE_MISC_BUFFER_STRUCTURED,
+ D3D11_CPU_ACCESS_FLAG(0) };
+ return result;
+};
+
+inline DxBufferFlags DxDynamicBufferPolicy()
+{
+ DxBufferFlags result = { D3D11_USAGE_DYNAMIC, D3D11_BIND_SHADER_RESOURCE,
+ D3D11_RESOURCE_MISC_BUFFER_STRUCTURED, D3D11_CPU_ACCESS_WRITE };
+ return result;
+};
+
+inline DxBufferFlags DxStagingBufferPolicy()
+{
+ DxBufferFlags result = { D3D11_USAGE_STAGING,
+ D3D11_BIND_FLAG(0),
+ D3D11_RESOURCE_MISC_BUFFER_STRUCTURED,
+ D3D11_CPU_ACCESS_FLAG(D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ) };
+ return result;
+};
+
+template <typename T>
+class DxBuffer : public DxBufferFlags
+{
+ static const uint32_t SizeOfT = sizeof(T);
+
+ public:
+ DxBuffer(DxContextManagerCallback* manager, const DxBufferFlags& flags = DxDefaultBufferPolicy())
+ : DxBufferFlags(flags), mCapacity(0), mBuffer(0), mManager(manager), mResourceView(nullptr), mAccessView(nullptr)
+ {
+ }
+
+ DxBuffer(const T* first, const T* last, DxContextManagerCallback* manager,
+ const DxBufferFlags& flags = DxDefaultBufferPolicy())
+ : DxBufferFlags(flags), mCapacity(0), mBuffer(0), mManager(manager), mResourceView(nullptr), mAccessView(nullptr)
+ {
+ D3D11_SUBRESOURCE_DATA data = { first };
+ create(uint32_t(last - first), &data);
+ }
+
+ DxBuffer(const DxBuffer& other)
+ : DxBufferFlags(other), mCapacity(0), mBuffer(0), mManager(other.mManager), mResourceView(nullptr), mAccessView(nullptr)
+ {
+ operator=(other);
+ }
+
+ ~DxBuffer()
+ {
+ if (mAccessView)
+ mAccessView->Release();
+ if (mResourceView)
+ mResourceView->Release();
+ if (mBuffer)
+ mBuffer->Release();
+ }
+
+ DxBuffer& operator = (const DxBuffer& other)
+ {
+ if (mCapacity < other.mCapacity)
+ {
+ if (mBuffer)
+ mBuffer->Release();
+
+ create(other.mCapacity);
+ }
+
+ if (other.mCapacity)
+ {
+ CD3D11_BOX box(0, 0, 0, other.mCapacity * SizeOfT, 1, 1);
+ context()->CopySubresourceRegion(mBuffer, 0, 0, 0, 0, other.mBuffer, 0, &box);
+ }
+
+ return *this;
+ }
+
+ ID3D11DeviceContext* context() const
+ {
+ return mManager->getContext();
+ }
+
+ void reserve(uint32_t n)
+ {
+ if (n <= mCapacity)
+ return;
+
+ ID3D11Buffer* oldBuffer = mBuffer;
+ CD3D11_BOX box(0, 0, 0, mCapacity * SizeOfT, 1, 1);
+
+ create(n);
+
+ if (oldBuffer)
+ {
+ context()->CopySubresourceRegion(mBuffer, 0, 0, 0, 0, oldBuffer, 0, &box);
+ oldBuffer->Release();
+ }
+ }
+
+ T* map(D3D11_MAP mapType)
+ {
+ D3D11_MAPPED_SUBRESOURCE map;
+ checkSuccess(context()->Map(mBuffer, 0, mapType, 0, &map));
+ return (T*)map.pData;
+ }
+
+ void unmap()
+ {
+ context()->Unmap(mBuffer, 0);
+ }
+
+ ID3D11ShaderResourceView* resourceView()
+ {
+ if (!mResourceView && mBuffer)
+ mManager->getDevice()->CreateShaderResourceView(mBuffer, NULL, &mResourceView);
+ return mResourceView;
+ }
+
+ ID3D11UnorderedAccessView* accessView()
+ {
+ if (!mAccessView && mBuffer)
+ mManager->getDevice()->CreateUnorderedAccessView(mBuffer, NULL, &mAccessView);
+ return mAccessView;
+ }
+
+ private:
+ void create(uint32_t capacity, D3D11_SUBRESOURCE_DATA* data = 0)
+ {
+ CD3D11_BUFFER_DESC desc(capacity * SizeOfT, mBindFlag, mUsage, mCpuAccessFlag, mMiscFlag, SizeOfT);
+ checkSuccess(mManager->getDevice()->CreateBuffer(&desc, data, &mBuffer));
+ mCapacity = capacity;
+
+ if (mResourceView)
+ mResourceView->Release();
+ mResourceView = nullptr;
+
+ if (mAccessView)
+ mAccessView->Release();
+ mAccessView = nullptr;
+ }
+
+ public:
+ uint32_t mCapacity;
+ ID3D11Buffer* mBuffer;
+ DxContextManagerCallback* mManager;
+ ID3D11ShaderResourceView* mResourceView;
+ ID3D11UnorderedAccessView* mAccessView;
+};
+
+// STL-style vector that holds POD types in DX device memory. The interface
+// is not complete, add whatever you need from the std::vector interface.
+template <typename T>
+class DxDeviceVector
+{
+ static const uint32_t SizeOfT = sizeof(T);
+
+ public:
+ DxDeviceVector(DxContextManagerCallback* manager, const DxBufferFlags& flags = DxDefaultBufferPolicy())
+ : mBuffer(manager, flags), mSize(0)
+ {
+ }
+
+ DxDeviceVector(const T* first, const T* last, DxContextManagerCallback* manager,
+ const DxBufferFlags& flags = DxDefaultBufferPolicy())
+ : mBuffer(first, last, manager, flags)
+ {
+ }
+
+ DxDeviceVector(const DxDeviceVector& other) : mBuffer(other.mBuffer), mSize(other.mSize)
+ {
+ }
+
+ template <typename Alloc>
+ DxDeviceVector& operator = (const physx::shdfnd::Array<T, Alloc>& other)
+ {
+ assign(other.begin(), other.end());
+ return *this;
+ }
+
+ uint32_t capacity() const
+ {
+ return mBuffer.mCapacity;
+ }
+ bool empty() const
+ {
+ return !mSize;
+ }
+ uint32_t size() const
+ {
+ return mSize;
+ }
+
+ void reserve(uint32_t n)
+ {
+ mBuffer.reserve(n);
+ }
+
+ void resize(uint32_t n)
+ {
+ if (mBuffer.mCapacity < n)
+ reserve(std::max(n, mBuffer.mCapacity * 2));
+ mSize = n;
+ }
+
+ void assign(const T* first, const T* last)
+ {
+ mSize = uint32_t(last - first);
+
+ if (!mSize)
+ return;
+
+ if (mSize > mBuffer.mCapacity)
+ {
+ mBuffer = DxBuffer<T>(first, last, mBuffer.mManager, mBuffer);
+ }
+ else
+ {
+ if (mBuffer.mUsage == D3D11_USAGE_DEFAULT)
+ {
+ CD3D11_BOX box(0, 0, 0, mSize * SizeOfT, 1, 1);
+ mBuffer.context()->UpdateSubresource(mBuffer.mBuffer, 0, &box, first, 0, 0);
+ }
+ else
+ {
+ memcpy(map(D3D11_MAP_WRITE_DISCARD), first, mSize * SizeOfT);
+ unmap();
+ }
+ }
+ }
+
+ void swap(DxDeviceVector& other)
+ {
+ physx::shdfnd::swap(mBuffer, other.mBuffer);
+ physx::shdfnd::swap(mSize, other.mSize);
+ }
+
+ T* map(D3D11_MAP mapType)
+ {
+ return mBuffer.map(mapType);
+ }
+
+ void unmap()
+ {
+ mBuffer.unmap();
+ }
+
+ // common interface with DxBatchedVector for DxVectorMap
+ DxContextManagerCallback* manager() const
+ {
+ return mBuffer.mManager;
+ }
+
+ public:
+ DxBuffer<T> mBuffer;
+ uint32_t mSize;
+};
+
+template <typename Vector>
+class DxVectorMap : DxContextLock
+{
+ DxVectorMap& operator = (const DxVectorMap&);
+
+ public:
+ typedef typename Vector::ValueType ValueType;
+
+ DxVectorMap(Vector& vector, D3D11_MAP mapType = D3D11_MAP_READ_WRITE)
+ : DxContextLock(vector.manager()), mVector(vector), mData(mVector.map(mapType))
+ {
+ }
+
+ ~DxVectorMap()
+ {
+ if (mData)
+ mVector.unmap();
+ }
+
+ // not actually initializing values!
+ void resize(uint32_t size, const ValueType& = ValueType())
+ {
+ NV_CLOTH_ASSERT(size <= mVector.capacity());
+ return mVector.resize(size);
+ }
+
+ uint32_t size() const
+ {
+ return mVector.size();
+ }
+
+ ValueType* begin()
+ {
+ return mData;
+ }
+
+ ValueType* end()
+ {
+ return mData + mVector.mSize;
+ }
+
+ ValueType& operator[](uint32_t i)
+ {
+ return mData[i];
+ }
+
+ void pushBack(const ValueType& value)
+ {
+ NV_CLOTH_ASSERT(mVector.mCapacity > mVector.mSize);
+ mData[mVector.mSize++] = value;
+ }
+
+ void replaceWithLast(ValueType* it)
+ {
+ *it = mData[--mVector.mSize];
+ }
+
+ private:
+ Vector& mVector;
+ ValueType* const mData;
+};
+
+} // namespace cloth
+
+} // namespace nv
+
+namespace physx
+{
+namespace shdfnd
+{
+template <typename T>
+void swap(nv::cloth::DxBuffer<T>& left, nv::cloth::DxBuffer<T>& right)
+{
+ swap(left.mCapacity, right.mCapacity);
+ swap(left.mBuffer, right.mBuffer);
+ swap(left.mManager, right.mManager);
+ swap(left.mResourceView, right.mResourceView);
+ swap(left.mAccessView, right.mAccessView);
+}
+}
+}