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 /PhysX_3.4/Samples/SampleFramework/renderer/src/RendererParticleSystemShape.cpp | |
| 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 'PhysX_3.4/Samples/SampleFramework/renderer/src/RendererParticleSystemShape.cpp')
| -rw-r--r-- | PhysX_3.4/Samples/SampleFramework/renderer/src/RendererParticleSystemShape.cpp | 643 |
1 files changed, 643 insertions, 0 deletions
diff --git a/PhysX_3.4/Samples/SampleFramework/renderer/src/RendererParticleSystemShape.cpp b/PhysX_3.4/Samples/SampleFramework/renderer/src/RendererParticleSystemShape.cpp new file mode 100644 index 00000000..06e62043 --- /dev/null +++ b/PhysX_3.4/Samples/SampleFramework/renderer/src/RendererParticleSystemShape.cpp @@ -0,0 +1,643 @@ +// 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-2016 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. +#include <PsUtilities.h> + +#include <RendererParticleSystemShape.h> + +#include <Renderer.h> + +#include <RendererMemoryMacros.h> +#include <RendererIndexBuffer.h> +#include <RendererIndexBufferDesc.h> +#include <RendererVertexBuffer.h> +#include <RendererVertexBufferDesc.h> +#include <RendererInstanceBuffer.h> +#include <RendererInstanceBufferDesc.h> +#include <RendererMesh.h> +#include <RendererMeshDesc.h> +#include "PsUtilities.h" +#include "PsBitUtils.h" + +using namespace SampleRenderer; +using namespace physx::shdfnd; + +PxReal convexVertices[] = { 0.0f, 1.0f, 0.0f, // 1 up face + 0.5f, 0.0f, 0.5f, + 0.5f, 0.0f, -0.5f, + 0.0f, 1.0f, 0.0f, // 2 up face + 0.5f, 0.0f, -0.5f, + -0.5f, 0.0f, -0.5f, + 0.0f, 1.0f, 0.0f, // 3 up face + -0.5f, 0.0f, -0.5f, + -0.5f, 0.0f, 0.5f, + 0.0f, 1.0f, 0.0f, // 4 up face + -0.5f, 0.0f, 0.5f, + 0.5f, 0.0f, 0.5f, + 0.0f, -1.0f, 0.0f, // 1 down face + 0.5f, 0.0f, 0.5f, + 0.5f, 0.0f, -0.5f, + 0.0f, -1.0f, 0.0f, // 2 down face + 0.5f, 0.0f, -0.5f, + -0.5f, 0.0f, -0.5f, + 0.0f, -1.0f, 0.0f, // 3 down face + -0.5f, 0.0f, -0.5f, + -0.5f, 0.0f, 0.5f, + 0.0f, -1.0f, 0.0f, // 4 down face + -0.5f, 0.0f, 0.5f, + 0.5f, 0.0f, 0.5f }; +PxReal convexTexcoords[] = { 0.0f, 0.0f, // each face + 0.0f, 1.0f, + 1.0f, 0.0f }; +PxReal convexNormals[] = { 1.0f, -0.5f, 0.0f, // 1 up face + 1.0f, -0.5f, 0.0f, + 1.0f, -0.5f, 0.0f, + 0.0f, -0.5f, -1.0f, // 2 up face + 0.0f, -0.5f, -1.0f, + 0.0f, -0.5f, -1.0f, + -1.0f, -0.5f, 0.0f, // 3 up face + -1.0f, -0.5f, 0.0f, + -1.0f, -0.5f, 0.0f, + 0.0f, -0.5f, 1.0f, // 4 up face + 0.0f, -0.5f, 1.0f, + 0.0f, -0.5f, 1.0f, + 1.0f, 0.5f, 0.0f, // 1 down face + 1.0f, 0.5f, 0.0f, + 1.0f, 0.5f, 0.0f, + 0.0f, 0.5f, -1.0f, // 2 down face + 0.0f, 0.5f, -1.0f, + 0.0f, 0.5f, -1.0f, + -1.0f, -0.5f, 0.0f, // 3 down face + -1.0f, -0.5f, 0.0f, + -1.0f, -0.5f, 0.0f, + 0.0f, -0.5f, 1.0f, // 4 down face + 0.0f, -0.5f, 1.0f, + 0.0f, -0.5f, 1.0f }; +PxU32 convexIndices[] = { 0, 1, 2, + 3, 4, 5, + 6, 7, 8, + 9, 10, 11, + 12, 13, 14, + 15, 16, 17, + 18, 19, 20, + 21, 22, 23 }; + +const PxU32 convexVerticesCount = PX_ARRAY_SIZE(convexVertices) / 3 ; +const PxU32 convexIndicesCount = PX_ARRAY_SIZE(convexIndices); +//const PxU32 convexNormalsCount = PX_ARRAY_SIZE(convexNormals) / 3; +//const PxU32 convexTexcoordsCount = PX_ARRAY_SIZE(convexTexcoords) / 2; + +#if defined(RENDERER_ENABLE_CUDA_INTEROP) +#include <task/PxTask.h> +#include <cuda.h> + +// pre-compiled fatbin +#if defined(_M_X64) +#include "cuda/RenderParticles_x64.cuh" +#else +#include "cuda/RenderParticles_x86.cuh" +#endif + +namespace +{ + CUmodule gParticlesCuRenderModule; + CUfunction gParticlesCuUpdateInstanceFunc; + CUfunction gParticlesCuUpdateBillboardFunc; + + void checkSuccess(CUresult r) + { + PX_ASSERT(r == CUDA_SUCCESS); + } +} + +#endif // RENDERER_ENABLE_CUDA_INTEROP + +RendererParticleSystemShape::RendererParticleSystemShape(Renderer &renderer, + PxU32 _mMaxParticles, bool _mInstanced, bool _mFading, + PxReal fadingPeriod, PxReal debriScaleFactor, PxCudaContextManager* ctxMgr) : + RendererShape(renderer), + mInstanced(_mInstanced), + mFading(_mFading), + mFadingPeriod(fadingPeriod), + mMaxParticles(_mMaxParticles), + mInstanceBuffer(NULL), + mIndexBuffer(NULL), + mCtxMgr(ctxMgr) +{ + for(PxU32 i = 0; i < NUM_VERTEX_BUFFERS; i++ ) + { + mVertexBuffer[i] = NULL; + } + RendererVertexBufferDesc vbdesc; + +#if defined(RENDERER_ENABLE_CUDA_INTEROP) + if (ctxMgr) + { + vbdesc.registerInCUDA = true; + vbdesc.interopContext = ctxMgr; + + ctxMgr->acquireContext(); + + // find module containing our kernel + CUresult success; + + success = cuModuleLoadDataEx(&gParticlesCuRenderModule, updateParticleVertexBuffer, 0, NULL, NULL); + RENDERER_ASSERT(success == CUDA_SUCCESS, "Could not load cloth render CUDA module."); + + success = cuModuleGetFunction(&gParticlesCuUpdateInstanceFunc, gParticlesCuRenderModule, "updateInstancedVB"); + RENDERER_ASSERT(success == CUDA_SUCCESS, "Could not find cloth render CUDA function."); + + success = cuModuleGetFunction(&gParticlesCuUpdateBillboardFunc, gParticlesCuRenderModule, "updateBillboardVB"); + RENDERER_ASSERT(success == CUDA_SUCCESS, "Could not find cloth render CUDA function."); + + ctxMgr->releaseContext(); + } +#endif //RENDERER_ENABLE_CUDA_INTEROP + + if(mInstanced) + { + vbdesc.hint = RendererVertexBuffer::HINT_STATIC; + vbdesc.maxVertices = convexVerticesCount; + } + else + { +#if defined(RENDERER_TABLET) + vbdesc.hint = RendererVertexBuffer::HINT_STATIC; +#else + vbdesc.hint = RendererVertexBuffer::HINT_DYNAMIC; +#endif + vbdesc.maxVertices = mMaxParticles; + } + { + RendererVertexBufferDesc vbdesc_l = vbdesc; + vbdesc_l.semanticFormats[RendererVertexBuffer::SEMANTIC_POSITION] = RendererVertexBuffer::FORMAT_FLOAT3; + mVertexBuffer[DYNAMIC_POS_VB] = m_renderer.createVertexBuffer(vbdesc_l); + RENDERER_ASSERT(mVertexBuffer[DYNAMIC_POS_VB], "Failed to create Vertex Buffer."); + } + { + RendererVertexBufferDesc vbdesc_l = vbdesc; + vbdesc_l.semanticFormats[RendererVertexBuffer::SEMANTIC_COLOR] = RendererVertexBuffer::FORMAT_COLOR_NATIVE; + mVertexBuffer[DYNAMIC_COL_VB] = m_renderer.createVertexBuffer(vbdesc_l); + RENDERER_ASSERT(mVertexBuffer[DYNAMIC_COL_VB], "Failed to create Vertex Buffer."); + } + vbdesc.hint = RendererVertexBuffer::HINT_STATIC; + vbdesc.semanticFormats[RendererVertexBuffer::SEMANTIC_NORMAL] = RendererVertexBuffer::FORMAT_FLOAT3; + vbdesc.semanticFormats[RendererVertexBuffer::SEMANTIC_TEXCOORD0] = RendererVertexBuffer::FORMAT_FLOAT2; + mVertexBuffer[STATIC_VB] = m_renderer.createVertexBuffer(vbdesc); + RENDERER_ASSERT(mVertexBuffer[STATIC_VB], "Failed to create Vertex Buffer."); + // if enabled mInstanced meshes -> create instance buffer + if(mInstanced) + { + // create index buffer + RendererIndexBufferDesc inbdesc; + inbdesc.hint = RendererIndexBuffer::HINT_STATIC; + inbdesc.format = RendererIndexBuffer::FORMAT_UINT32; + inbdesc.maxIndices = convexIndicesCount; + mIndexBuffer = m_renderer.createIndexBuffer(inbdesc); + RENDERER_ASSERT(mIndexBuffer, "Failed to create Instance Buffer."); + // create instance buffer + RendererInstanceBufferDesc ibdesc; + ibdesc.hint = RendererInstanceBuffer::HINT_DYNAMIC; + ibdesc.semanticFormats[RendererInstanceBuffer::SEMANTIC_POSITION] = RendererInstanceBuffer::FORMAT_FLOAT3; + ibdesc.semanticFormats[RendererInstanceBuffer::SEMANTIC_NORMALX] = RendererInstanceBuffer::FORMAT_FLOAT3; + ibdesc.semanticFormats[RendererInstanceBuffer::SEMANTIC_NORMALY] = RendererInstanceBuffer::FORMAT_FLOAT3; + ibdesc.semanticFormats[RendererInstanceBuffer::SEMANTIC_NORMALZ] = RendererInstanceBuffer::FORMAT_FLOAT3; + ibdesc.semanticFormats[RendererInstanceBuffer::SEMANTIC_VELOCITY_LIFE] = RendererInstanceBuffer::FORMAT_FLOAT4; + ibdesc.maxInstances = mMaxParticles; + + if (ctxMgr) + { + ibdesc.registerInCUDA = true; + ibdesc.interopContext = ctxMgr; + } + + mInstanceBuffer = m_renderer.createInstanceBuffer(ibdesc); + RENDERER_ASSERT(mInstanceBuffer, "Failed to create Instance Buffer."); + } + PxU32 color = renderer.convertColor(RendererColor(255, 255, 255, 255)); + PxU32 numInstances = 0; + RendererMesh::Primitive primitive = RendererMesh::PRIMITIVE_POINT_SPRITES; + if(mInstanced) + { + numInstances = mMaxParticles; + initializeBuffersAsSimpleConvex(color, debriScaleFactor); + initializeInstanceBuffer(); + primitive = RendererMesh::PRIMITIVE_TRIANGLES; + } + else + { + initializeVertexBuffer(color); + } + if(mVertexBuffer[DYNAMIC_POS_VB] && mVertexBuffer[DYNAMIC_COL_VB] && mVertexBuffer[STATIC_VB]) + { + RendererMeshDesc meshdesc; + meshdesc.primitives = primitive; + meshdesc.vertexBuffers = mVertexBuffer; + meshdesc.numVertexBuffers = NUM_VERTEX_BUFFERS; + meshdesc.firstVertex = 0; + meshdesc.numVertices = mVertexBuffer[STATIC_VB]->getMaxVertices(); + meshdesc.indexBuffer = mIndexBuffer; + meshdesc.firstIndex = 0; + if(mIndexBuffer) + { + meshdesc.numIndices = mIndexBuffer->getMaxIndices(); + } + else + { + meshdesc.numIndices = 0; + } + meshdesc.instanceBuffer = mInstanceBuffer; + meshdesc.firstInstance = 0; + meshdesc.numInstances = numInstances; + m_mesh = m_renderer.createMesh(meshdesc); + RENDERER_ASSERT(m_mesh, "Failed to create Mesh."); + } +} + +RendererParticleSystemShape::~RendererParticleSystemShape(void) +{ + SAFE_RELEASE(mInstanceBuffer); + SAFE_RELEASE(mIndexBuffer); + for(PxU32 i = 0; i < NUM_VERTEX_BUFFERS; i++ ) + { + SAFE_RELEASE(mVertexBuffer[i]); + } + SAFE_RELEASE(m_mesh); +} + +void RendererParticleSystemShape::initializeBuffersAsSimpleConvex(PxU32 color, PxReal scaleFactor) +{ + // initialize vertex buffer + PxU32 positionStride = 0, colorStride = 0, texcoordStride = 0, normalStride = 0; + PxU8* locked_normals = static_cast<PxU8*>(mVertexBuffer[STATIC_VB]->lockSemantic(RendererVertexBuffer::SEMANTIC_NORMAL, normalStride)); + PxU8* locked_texcoords = static_cast<PxU8*>(mVertexBuffer[STATIC_VB]->lockSemantic(RendererVertexBuffer::SEMANTIC_TEXCOORD0, texcoordStride)); + PxU8* locked_positions = static_cast<PxU8*>(mVertexBuffer[DYNAMIC_POS_VB]->lockSemantic(RendererVertexBuffer::SEMANTIC_POSITION, positionStride)); + PxU8* locked_colors = static_cast<PxU8*>(mVertexBuffer[DYNAMIC_COL_VB]->lockSemantic(RendererVertexBuffer::SEMANTIC_COLOR, colorStride)); + PxU32 maxVertices = mVertexBuffer[STATIC_VB]->getMaxVertices(); + for(PxU32 i = 0; i < maxVertices; ++i, + locked_positions += positionStride, + locked_colors += colorStride, + locked_texcoords += texcoordStride, + locked_normals += normalStride) + { + PxReal localConvexVertices[] = { convexVertices[3 * i + 0] * scaleFactor, + convexVertices[3 * i + 1] * scaleFactor, + convexVertices[3 * i + 2] * scaleFactor }; + PxReal localConvexNormals[] = { convexNormals[3 * i + 0] / 2.25f, + convexNormals[3 * i + 1] / 2.25f, + convexNormals[3 * i + 2] / 2.25f }; + memcpy(locked_positions, localConvexVertices, sizeof(PxReal) * 3); + memcpy(locked_normals, localConvexNormals, sizeof(PxReal) * 3); + memcpy(locked_texcoords, convexTexcoords + 2 * (i % 3), sizeof(PxReal) * 2); + memset(locked_colors, color, sizeof(PxU32)); + } + mVertexBuffer[STATIC_VB]->unlockSemantic(RendererVertexBuffer::SEMANTIC_TEXCOORD0); + mVertexBuffer[STATIC_VB]->unlockSemantic(RendererVertexBuffer::SEMANTIC_NORMAL); + mVertexBuffer[DYNAMIC_COL_VB]->unlockSemantic(RendererVertexBuffer::SEMANTIC_COLOR); + mVertexBuffer[DYNAMIC_POS_VB]->unlockSemantic(RendererVertexBuffer::SEMANTIC_POSITION); + // initialize index buffer + PxU32* locked_indices = static_cast<PxU32*>(mIndexBuffer->lock()); + memcpy(locked_indices, convexIndices, mIndexBuffer->getMaxIndices() * sizeof(PxU32)); + mIndexBuffer->unlock(); +} + +void RendererParticleSystemShape::initializeVertexBuffer(PxU32 color) +{ + PxU32 positionStride = 0, colorStride = 0; + PxU8* locked_positions = static_cast<PxU8*>(mVertexBuffer[DYNAMIC_POS_VB]->lockSemantic(RendererVertexBuffer::SEMANTIC_POSITION, positionStride)); + PxU8* locked_colors = static_cast<PxU8*>(mVertexBuffer[DYNAMIC_COL_VB]->lockSemantic(RendererVertexBuffer::SEMANTIC_COLOR, colorStride)); + for(PxU32 i = 0; i < mMaxParticles; ++i, + locked_positions += positionStride, + locked_colors += colorStride) + { + memset(locked_positions, 0, sizeof(PxReal) * 3); + memset(locked_colors, color, sizeof(PxU32)); + } + mVertexBuffer[DYNAMIC_COL_VB]->unlockSemantic(RendererVertexBuffer::SEMANTIC_COLOR); + mVertexBuffer[DYNAMIC_POS_VB]->unlockSemantic(RendererVertexBuffer::SEMANTIC_POSITION); +} + +void RendererParticleSystemShape::initializeInstanceBuffer() +{ + PxU32 positionStride = 0, + normalXStride = 0, + normalYStride = 0, + normalZStride = 0, + velocityLifeStride = 0; + PxU8* locked_positions = static_cast<PxU8*>(mInstanceBuffer->lockSemantic( + RendererInstanceBuffer::SEMANTIC_POSITION, positionStride)); + PxU8* locked_normalsx = static_cast<PxU8*>(mInstanceBuffer->lockSemantic( + RendererInstanceBuffer::SEMANTIC_NORMALX, normalXStride)); + PxU8* locked_normalsy = static_cast<PxU8*>(mInstanceBuffer->lockSemantic( + RendererInstanceBuffer::SEMANTIC_NORMALY, normalYStride)); + PxU8* locked_normalsz = static_cast<PxU8*>(mInstanceBuffer->lockSemantic( + RendererInstanceBuffer::SEMANTIC_NORMALZ, normalZStride)); + PxU8* locked_velocitylife = static_cast<PxU8*>(mInstanceBuffer->lockSemantic( + RendererInstanceBuffer::SEMANTIC_VELOCITY_LIFE, velocityLifeStride)); + // fill buffer here + PxReal normalx[] = { 1.0f, 0.0f, 0.0f }; + PxReal normaly[] = { 0.0f, 1.0f, 0.0f }; + PxReal normalz[] = { 0.0f, 0.0f, 1.0f }; + for(PxU32 i = 0; i < mMaxParticles; ++i, + locked_positions += positionStride, + locked_normalsx += normalXStride, + locked_normalsy += normalYStride, + locked_normalsz += normalZStride, + locked_velocitylife += velocityLifeStride) + { + memset(locked_positions, 0, sizeof(PxReal) * 3); + memcpy(locked_normalsx, normalx, sizeof(physx::PxVec3)); + memcpy(locked_normalsy, normaly, sizeof(physx::PxVec3)); + memcpy(locked_normalsz, normalz, sizeof(physx::PxVec3)); + memset(locked_velocitylife, 0, sizeof(PxReal) * 4); + } + mInstanceBuffer->unlockSemantic(RendererInstanceBuffer::SEMANTIC_VELOCITY_LIFE); + mInstanceBuffer->unlockSemantic(RendererInstanceBuffer::SEMANTIC_NORMALZ); + mInstanceBuffer->unlockSemantic(RendererInstanceBuffer::SEMANTIC_NORMALY); + mInstanceBuffer->unlockSemantic(RendererInstanceBuffer::SEMANTIC_NORMALX); + mInstanceBuffer->unlockSemantic(RendererInstanceBuffer::SEMANTIC_POSITION); +} + +namespace +{ + +#if defined(RENDERER_ENABLE_CUDA_INTEROP) + + void cuuAlignUp(int* offset, int alignment) + { + *offset = ((*offset) + (alignment) - 1) & ~((alignment) - 1); + } + + template <typename T, typename T2> CUresult + cuuParamSet(CUfunction hf, int* offset, const T2& var) + { + cuuAlignUp(offset, __alignof(T)); + CUresult err = cuParamSetv(hf, *offset, (void*)&var, sizeof(T)); + *offset += sizeof(T); + return err; + } + +#endif // RENDERER_ENABLE_CUDA_INTEROP + +} // anonymous namespace + + +bool RendererParticleSystemShape::updateInstanced(PxU32 validParticleRange, + CUdeviceptr positions, + CUdeviceptr validParticleBitmap, + CUdeviceptr orientations, + PxU32 numParticles) +{ +#if defined(RENDERER_ENABLE_CUDA_INTEROP) + + CUgraphicsResource res; + if (mInstanceBuffer->getInteropResourceHandle(res)) + { + mCtxMgr->acquireContext(); + + checkSuccess(cuGraphicsMapResources(1, &res, 0)); + + CUdeviceptr destBuffer; + size_t destSize; + cuGraphicsResourceGetMappedPointer(&destBuffer, &destSize, res); + + // if either buffers could not be mapped abort + if (!destBuffer) + { + mCtxMgr->releaseContext(); + return false; + } + + int offset = 0; + checkSuccess(cuuParamSet<CUdeviceptr>(gParticlesCuUpdateInstanceFunc, &offset, destBuffer + mInstanceBuffer->getOffsetForSemantic(RendererInstanceBuffer::SEMANTIC_POSITION))); + checkSuccess(cuuParamSet<CUdeviceptr>(gParticlesCuUpdateInstanceFunc, &offset, destBuffer + mInstanceBuffer->getOffsetForSemantic(RendererInstanceBuffer::SEMANTIC_NORMALX))); + checkSuccess(cuuParamSet<CUdeviceptr>(gParticlesCuUpdateInstanceFunc, &offset, destBuffer + mInstanceBuffer->getOffsetForSemantic(RendererInstanceBuffer::SEMANTIC_NORMALY))); + checkSuccess(cuuParamSet<CUdeviceptr>(gParticlesCuUpdateInstanceFunc, &offset, destBuffer + mInstanceBuffer->getOffsetForSemantic(RendererInstanceBuffer::SEMANTIC_NORMALZ))); + checkSuccess(cuuParamSet<PxU32>(gParticlesCuUpdateInstanceFunc, &offset, mInstanceBuffer->getStride())); + checkSuccess(cuuParamSet<CUdeviceptr>(gParticlesCuUpdateInstanceFunc, &offset, positions)); + checkSuccess(cuuParamSet<CUdeviceptr>(gParticlesCuUpdateInstanceFunc, &offset, orientations)); + checkSuccess(cuuParamSet<CUdeviceptr>(gParticlesCuUpdateInstanceFunc, &offset, validParticleBitmap)); + checkSuccess(cuuParamSet<PxU32>(gParticlesCuUpdateInstanceFunc, &offset, validParticleRange)); + checkSuccess(cuParamSetSize(gParticlesCuUpdateInstanceFunc, offset)); + + const PxU32 blockSize = 512; + const PxU32 numBlocks = 1; + + checkSuccess(cuFuncSetBlockShape(gParticlesCuUpdateInstanceFunc, blockSize, 1, 1)); + checkSuccess(cuLaunchGridAsync(gParticlesCuUpdateInstanceFunc, numBlocks, 1, 0)); + + checkSuccess(cuGraphicsUnmapResources(1, &res, 0)); + + mCtxMgr->releaseContext(); + } + + m_mesh->setInstanceBufferRange(0, numParticles); + +#endif // RENDERER_ENABLE_CUDA_INTEROP + + return true; + +} + +bool RendererParticleSystemShape::updateBillboard(PxU32 validParticleRange, + CUdeviceptr positions, + CUdeviceptr validParticleBitmap, + CUdeviceptr lifetimes, + PxU32 numParticles) +{ + +#if defined(RENDERER_ENABLE_CUDA_INTEROP) + + CUgraphicsResource res[2]; + mVertexBuffer[DYNAMIC_POS_VB]->getInteropResourceHandle(res[0]); + mVertexBuffer[DYNAMIC_COL_VB]->getInteropResourceHandle(res[1]); + + if (res[0] && res[1]) + { + mCtxMgr->acquireContext(); + + checkSuccess(cuGraphicsMapResources(2, res, 0)); + + CUdeviceptr posBuffer, colBuffer; + size_t destSize; + checkSuccess(cuGraphicsResourceGetMappedPointer(&posBuffer, &destSize, res[0])); + checkSuccess(cuGraphicsResourceGetMappedPointer(&colBuffer, &destSize, res[1])); + + // if either buffers could not be mapped abort + if (!posBuffer || !colBuffer) + { + mCtxMgr->releaseContext(); + return false; + } + + int offset = 0; + checkSuccess(cuuParamSet<CUdeviceptr>(gParticlesCuUpdateBillboardFunc, &offset, posBuffer)); + checkSuccess(cuuParamSet<CUdeviceptr>(gParticlesCuUpdateBillboardFunc, &offset, colBuffer+3)); + checkSuccess(cuuParamSet<PxU32>(gParticlesCuUpdateBillboardFunc, &offset, mVertexBuffer[DYNAMIC_POS_VB]->getStride())); + checkSuccess(cuuParamSet<PxF32>(gParticlesCuUpdateBillboardFunc, &offset, mFadingPeriod)); + checkSuccess(cuuParamSet<CUdeviceptr>(gParticlesCuUpdateBillboardFunc, &offset, positions)); + checkSuccess(cuuParamSet<CUdeviceptr>(gParticlesCuUpdateBillboardFunc, &offset, lifetimes)); + checkSuccess(cuuParamSet<CUdeviceptr>(gParticlesCuUpdateBillboardFunc, &offset, validParticleBitmap)); + checkSuccess(cuuParamSet<PxU32>(gParticlesCuUpdateBillboardFunc, &offset, validParticleRange)); + checkSuccess(cuParamSetSize(gParticlesCuUpdateBillboardFunc, offset)); + + const PxU32 blockSize = 512; + const PxU32 numBlocks = 1; + + checkSuccess(cuFuncSetBlockShape(gParticlesCuUpdateBillboardFunc, blockSize, 1, 1)); + checkSuccess(cuLaunchGridAsync(gParticlesCuUpdateBillboardFunc, numBlocks, 1, 0)); + + checkSuccess(cuGraphicsUnmapResources(2, res, 0)); + + mCtxMgr->releaseContext(); + } + + m_mesh->setVertexBufferRange(0, numParticles); + +#endif // RENDERER_ENABLE_CUDA_INTEROP + + return true; + +} + + +void RendererParticleSystemShape::updateInstanced(PxU32 validParticleRange, + const PxVec3* positions, + const PxU32* validParticleBitmap, + const PxMat33* orientation) +{ + PxU32 positionStride = 0, + normalXStride = 0, + normalYStride = 0, + normalZStride = 0; + PxU8 *locked_positions = NULL, + *locked_normalsx = NULL, + *locked_normalsy = NULL, + *locked_normalsz = NULL; + locked_positions = static_cast<PxU8*>(mInstanceBuffer->lockSemantic( + RendererInstanceBuffer::SEMANTIC_POSITION, positionStride)); + locked_normalsx = static_cast<PxU8*>(mInstanceBuffer->lockSemantic( + RendererInstanceBuffer::SEMANTIC_NORMALX, normalXStride)); + locked_normalsy = static_cast<PxU8*>(mInstanceBuffer->lockSemantic( + RendererInstanceBuffer::SEMANTIC_NORMALY, normalYStride)); + locked_normalsz = static_cast<PxU8*>(mInstanceBuffer->lockSemantic( + RendererInstanceBuffer::SEMANTIC_NORMALZ, normalZStride)); + + // update vertex or instance buffer here + PxU32 numParticles = 0; + if(validParticleRange > 0) + { + for (PxU32 w = 0; w <= (validParticleRange-1) >> 5; w++) + { + for (PxU32 b = validParticleBitmap[w]; b; b &= b-1) + { + PxU32 index = (w << 5 | physx::shdfnd::lowestSetBit(b)); + + memcpy(locked_normalsx, &(orientation[index].column0), sizeof(PxVec3)); + memcpy(locked_normalsy, &(orientation[index].column1), sizeof(PxVec3)); + memcpy(locked_normalsz, &(orientation[index].column2), sizeof(PxVec3)); + memcpy(locked_positions, positions + index, sizeof(PxVec3)); + + locked_positions += positionStride; + locked_normalsx += normalXStride; + locked_normalsy += normalYStride; + locked_normalsz += normalZStride; + numParticles++; + } + } + } + + mInstanceBuffer->unlockSemantic(RendererInstanceBuffer::SEMANTIC_NORMALZ); + mInstanceBuffer->unlockSemantic(RendererInstanceBuffer::SEMANTIC_NORMALY); + mInstanceBuffer->unlockSemantic(RendererInstanceBuffer::SEMANTIC_NORMALX); + mInstanceBuffer->unlockSemantic(RendererInstanceBuffer::SEMANTIC_POSITION); + m_mesh->setInstanceBufferRange(0, numParticles); +} + +void RendererParticleSystemShape::updateBillboard(PxU32 validParticleRange, + const PxVec3* positions, + const PxU32* validParticleBitmap, + const PxReal* lifetime) +{ + PxU32 positionStride = 0, colorStride = 0; + PxU8 *locked_positions = NULL, *locked_colors = NULL; + locked_positions = static_cast<PxU8*>(mVertexBuffer[DYNAMIC_POS_VB]->lockSemantic( + RendererVertexBuffer::SEMANTIC_POSITION, positionStride)); + if(mFading && lifetime) + { + locked_colors = static_cast<PxU8*>(mVertexBuffer[DYNAMIC_COL_VB]->lockSemantic( + RendererVertexBuffer::SEMANTIC_COLOR, colorStride)); + // move ptr to alpha +#if !defined(RENDERER_XBOX360) + locked_colors += 3 * sizeof(PxU8); +#endif + } + // update vertex or instance buffer here + PxU32 numParticles = 0; + if(validParticleRange > 0) + { + for (PxU32 w = 0; w <= (validParticleRange-1) >> 5; w++) + { + for (PxU32 b = validParticleBitmap[w]; b; b &= b-1) + { + PxU32 index = (w << 5 | physx::shdfnd::lowestSetBit(b)); + *reinterpret_cast<PxVec3*>(locked_positions) = positions[index]; + locked_positions += positionStride; + if(mFading && lifetime) + { + PxU8 particle_lifetime = 0; + if(lifetime[index] >= mFadingPeriod) + { + particle_lifetime = 255; + } + else + { + if(lifetime[index] <= 0.0f) + { + particle_lifetime = 0; + } + else + { + particle_lifetime = static_cast<PxU8>(lifetime[index] * 255 / mFadingPeriod); + } + } + locked_colors[0] = particle_lifetime; + locked_colors += colorStride; + } + numParticles++; + } + } + } + + if(mFading && lifetime) + { + mVertexBuffer[DYNAMIC_COL_VB]->unlockSemantic(RendererVertexBuffer::SEMANTIC_COLOR); + } + mVertexBuffer[DYNAMIC_POS_VB]->unlockSemantic(RendererVertexBuffer::SEMANTIC_POSITION); + m_mesh->setVertexBufferRange(0, numParticles); +} |