浏览代码

Added immutable vertex and index buffers.

Dušan Jocić 9 年之前
父节点
当前提交
28d303c5ea

+ 24 - 4
Engine/source/gfx/D3D9/gfxD3D9Device.cpp

@@ -731,7 +731,8 @@ void GFXD3D9Device::setShader( GFXShader *shader, bool force )
 //-----------------------------------------------------------------------------
 GFXPrimitiveBuffer * GFXD3D9Device::allocPrimitiveBuffer(   U32 numIndices, 
                                                             U32 numPrimitives, 
-                                                            GFXBufferType bufferType )
+                                                            GFXBufferType bufferType,
+                                                            void* data )
 {
    // Allocate a buffer to return
    GFXD3D9PrimitiveBuffer * res = new GFXD3D9PrimitiveBuffer(this, numIndices, numPrimitives, bufferType);
@@ -741,12 +742,13 @@ GFXPrimitiveBuffer * GFXD3D9Device::allocPrimitiveBuffer(   U32 numIndices,
    D3DPOOL pool = D3DPOOL_DEFAULT;
 
    // Assumptions:
-   //    - static buffers are write once, use many
+   //    - static buffers are write rarely, use many
    //    - dynamic buffers are write many, use many
    //    - volatile buffers are write once, use once
    // You may never read from a buffer.
    switch(bufferType)
    {
+   case GFXBufferTypeImmutable:
    case GFXBufferTypeStatic:
       pool = isD3D9Ex() ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED;
       break;
@@ -781,6 +783,14 @@ GFXPrimitiveBuffer * GFXD3D9Device::allocPrimitiveBuffer(   U32 numIndices,
       D3D9Assert(mD3DDevice->CreateIndexBuffer( sizeof(U16) * numIndices , usage, GFXD3D9IndexFormat[GFXIndexFormat16], pool, &res->ib, 0),
          "Failed to allocate an index buffer.");
    }
+   
+   if(data)
+   {
+      void* dest;
+      res->lock(0, numIndices, &dest);
+      dMemcpy(dest, data, sizeof(U16) * numIndices);
+      res->unlock();
+   }
 
    return res;
 }
@@ -791,7 +801,8 @@ GFXPrimitiveBuffer * GFXD3D9Device::allocPrimitiveBuffer(   U32 numIndices,
 GFXVertexBuffer * GFXD3D9Device::allocVertexBuffer(   U32 numVerts, 
                                                       const GFXVertexFormat *vertexFormat, 
                                                       U32 vertSize, 
-                                                      GFXBufferType bufferType )
+                                                      GFXBufferType bufferType, 
+                                                      void* data)
 {
    PROFILE_SCOPE( GFXD3D9Device_allocVertexBuffer );
 
@@ -808,7 +819,7 @@ GFXVertexBuffer * GFXD3D9Device::allocVertexBuffer(   U32 numVerts,
    res->mNumVerts = 0;
 
    // Assumptions:
-   //    - static buffers are write once, use many
+   //    - static buffers are write rarely, use many
    //    - dynamic buffers are write many, use many
    //    - volatile buffers are write once, use once
    // You may never read from a buffer.
@@ -850,6 +861,15 @@ GFXVertexBuffer * GFXD3D9Device::allocVertexBuffer(   U32 numVerts,
    }
 
    res->mNumVerts = numVerts;
+   
+   if(data)
+   {
+      void* dest;
+      res->lock(0, numVerts, &dest);
+      dMemcpy(dest, data, vertSize * numVerts);
+      res->unlock();
+   }
+   
    return res;
 }
 

+ 4 - 2
Engine/source/gfx/D3D9/gfxD3D9Device.h

@@ -298,10 +298,12 @@ public:
    virtual GFXVertexBuffer* allocVertexBuffer(  U32 numVerts, 
                                                 const GFXVertexFormat *vertexFormat,
                                                 U32 vertSize,
-                                                GFXBufferType bufferType );
+                                                GFXBufferType bufferType,
+                                                void* data = NULL );
    virtual GFXPrimitiveBuffer *allocPrimitiveBuffer(  U32 numIndices, 
                                                       U32 numPrimitives, 
-                                                      GFXBufferType bufferType );
+                                                      GFXBufferType bufferType,
+                                                      void* data = NULL );
    virtual void deallocVertexBuffer( GFXD3D9VertexBuffer *vertBuff );
    virtual GFXVertexDecl* allocVertexDecl( const GFXVertexFormat *vertexFormat );
    virtual void setVertexDecl( const GFXVertexDecl *decl );

+ 1 - 0
Engine/source/gfx/D3D9/pc/gfxD3D9PrimitiveBuffer.pc.cpp

@@ -31,6 +31,7 @@ void GFXD3D9PrimitiveBuffer::lock(U32 indexStart, U32 indexEnd, void **indexPtr)
    U32 flags=0;
    switch(mBufferType)
    {
+   case GFXBufferTypeImmutable:
    case GFXBufferTypeStatic:
       // flags |= D3DLOCK_DISCARD;
       break;

+ 4 - 2
Engine/source/gfx/Null/gfxNullDevice.cpp

@@ -276,14 +276,16 @@ GFXNullDevice::~GFXNullDevice()
 GFXVertexBuffer *GFXNullDevice::allocVertexBuffer( U32 numVerts, 
                                                    const GFXVertexFormat *vertexFormat,
                                                    U32 vertSize, 
-                                                   GFXBufferType bufferType ) 
+                                                   GFXBufferType bufferType,
+                                                   void* data ) 
 {
    return new GFXNullVertexBuffer(GFX, numVerts, vertexFormat, vertSize, bufferType);
 }
 
 GFXPrimitiveBuffer *GFXNullDevice::allocPrimitiveBuffer( U32 numIndices, 
                                                          U32 numPrimitives, 
-                                                         GFXBufferType bufferType) 
+                                                         GFXBufferType bufferType,
+                                                         void* data ) 
 {
    return new GFXNullPrimitiveBuffer(GFX, numIndices, numPrimitives, bufferType);
 }

+ 4 - 2
Engine/source/gfx/Null/gfxNullDevice.h

@@ -115,10 +115,12 @@ protected:
    virtual GFXVertexBuffer *allocVertexBuffer(  U32 numVerts, 
                                                 const GFXVertexFormat *vertexFormat, 
                                                 U32 vertSize, 
-                                                GFXBufferType bufferType );
+                                                GFXBufferType bufferType,
+                                                void* data = NULL );
    virtual GFXPrimitiveBuffer *allocPrimitiveBuffer(  U32 numIndices, 
                                                       U32 numPrimitives, 
-                                                      GFXBufferType bufferType );
+                                                      GFXBufferType bufferType,
+                                                      void* data = NULL );
 
    virtual GFXVertexDecl* allocVertexDecl( const GFXVertexFormat *vertexFormat ) { return NULL; }
    virtual void setVertexDecl( const GFXVertexDecl *decl ) {  }

+ 4 - 2
Engine/source/gfx/gfxDevice.h

@@ -637,7 +637,8 @@ protected:
    virtual GFXVertexBuffer *allocVertexBuffer(  U32 numVerts, 
                                                 const GFXVertexFormat *vertexFormat, 
                                                 U32 vertSize, 
-                                                GFXBufferType bufferType ) = 0;
+                                                GFXBufferType bufferType,
+                                                void* data = NULL ) = 0;
 
    /// Called from GFXVertexFormat to allocate the hardware 
    /// specific vertex declaration for rendering.
@@ -674,7 +675,8 @@ protected:
    /// @note All index buffers use unsigned 16-bit indices.
    virtual GFXPrimitiveBuffer *allocPrimitiveBuffer(  U32 numIndices, 
                                                       U32 numPrimitives, 
-                                                      GFXBufferType bufferType ) = 0;
+                                                      GFXBufferType bufferType,
+                                                      void* data = NULL ) = 0;
 
    /// @}
 

+ 4 - 3
Engine/source/gfx/gfxEnums.h

@@ -39,8 +39,8 @@
 
 enum GFXBufferType
 {
-      GFXBufferTypeStatic,   ///< Static vertex buffers are created and filled one time.
-                   ///< incur a performance penalty.  Resizing a static vertex buffer is not
+      GFXBufferTypeStatic,   ///< Static vertex buffers are created and rarely updated.
+                   ///< Updating might incur a performance penalty.  Resizing a static vertex buffer is not
                    ///< allowed.
       GFXBufferTypeDynamic,  ///< Dynamic vertex buffers are meant for vertices that can be changed
                    ///< often.  Vertices written into dynamic vertex buffers will remain valid
@@ -48,7 +48,8 @@ enum GFXBufferType
                    ///< allowed.
       GFXBufferTypeVolatile, ///< Volatile vertex or index buffers are meant for vertices or indices that are essentially
                    ///< only used once.  They can be resized without any performance penalty.
-      
+      GFXBufferTypeImmutable, ///< Immutable buffers must specify the data when creating the buffer. Cannot be modified.
+
       GFXBufferType_COUNT ///< Number of buffer types.
 };
 

+ 13 - 0
Engine/source/gfx/gfxPrimitiveBuffer.cpp

@@ -80,3 +80,16 @@ void GFXPrimitiveBufferHandle::set(GFXDevice *theDevice, U32 indexCount, U32 pri
       getPointer()->mDebugCreationPath = desc;
 #endif
 }
+
+//-----------------------------------------------------------------------------
+// immutable
+//-----------------------------------------------------------------------------
+void GFXPrimitiveBufferHandle::immutable(GFXDevice *theDevice, U32 indexCount, U32 primitiveCount, void* data, String desc)
+{
+   StrongRefPtr<GFXPrimitiveBuffer>::operator=( theDevice->allocPrimitiveBuffer(indexCount, primitiveCount, GFXBufferTypeImmutable, data) );
+
+#ifdef TORQUE_DEBUG
+   if( desc.isNotEmpty() )
+      getPointer()->mDebugCreationPath = desc;
+#endif
+}

+ 2 - 0
Engine/source/gfx/gfxPrimitiveBuffer.h

@@ -140,6 +140,8 @@ public:
    }
 
    void set(GFXDevice *theDevice, U32 indexCount, U32 primitiveCount, GFXBufferType bufferType, String desc = String::EmptyString );
+   
+   void immutable(GFXDevice *theDevice, U32 indexCount, U32 primitiveCount, void* data, String desc = String::EmptyString );
 
    void lock(U16 **indexBuffer, GFXPrimitive **primitiveBuffer = NULL, U32 indexStart = 0, U32 indexEnd = 0)
    {

+ 30 - 7
Engine/source/gfx/gl/gfxGLDevice.cpp

@@ -355,23 +355,46 @@ GFXPrimitiveBuffer* GFXGLDevice::findVolatilePBO(U32 numIndices, U32 numPrimitiv
 GFXVertexBuffer *GFXGLDevice::allocVertexBuffer(   U32 numVerts, 
                                                    const GFXVertexFormat *vertexFormat, 
                                                    U32 vertSize, 
-                                                   GFXBufferType bufferType ) 
+                                                   GFXBufferType bufferType,
+                                                   void* data = NULL )  
 {
    if(bufferType == GFXBufferTypeVolatile)
       return findVolatileVBO(numVerts, vertexFormat, vertSize);
          
    GFXGLVertexBuffer* buf = new GFXGLVertexBuffer( GFX, numVerts, vertexFormat, vertSize, bufferType );
-   buf->registerResourceWithDevice(this);
+   buf->registerResourceWithDevice(this);   
+
+   if(data)
+   {
+      void* dest;
+      buf->lock(0, numVerts, &dest);
+      dMemcpy(dest, data, vertSize * numVerts);
+      buf->unlock();
+   }
+
    return buf;
 }
 
-GFXPrimitiveBuffer *GFXGLDevice::allocPrimitiveBuffer( U32 numIndices, U32 numPrimitives, GFXBufferType bufferType ) 
+GFXPrimitiveBuffer *GFXGLDevice::allocPrimitiveBuffer( U32 numIndices, U32 numPrimitives, GFXBufferType bufferType, void* data ) 
 {
+   GFXPrimitiveBuffer* buf
    if(bufferType == GFXBufferTypeVolatile)
-      return findVolatilePBO(numIndices, numPrimitives);
-         
-   GFXGLPrimitiveBuffer* buf = new GFXGLPrimitiveBuffer(GFX, numIndices, numPrimitives, bufferType);
-   buf->registerResourceWithDevice(this);
+   {
+      buf = findVolatilePBO(numIndices, numPrimitives);
+   }
+   else
+   {
+      buf = new GFXGLPrimitiveBuffer(GFX, numIndices, numPrimitives, bufferType);
+      buf->registerResourceWithDevice(this);
+   }
+   
+   if(data)
+   {
+      void* dest;
+      buf->lock(0, numIndices, &dest);
+      dMemcpy(dest, data, sizeof(U16) * numIndices);
+      buf->unlock();
+   }
    return buf;
 }
 

+ 3 - 2
Engine/source/gfx/gl/gfxGLDevice.h

@@ -173,8 +173,9 @@ protected:
    virtual GFXVertexBuffer *allocVertexBuffer(  U32 numVerts, 
                                                 const GFXVertexFormat *vertexFormat,
                                                 U32 vertSize, 
-                                                GFXBufferType bufferType );
-   virtual GFXPrimitiveBuffer *allocPrimitiveBuffer( U32 numIndices, U32 numPrimitives, GFXBufferType bufferType );
+                                                GFXBufferType bufferType,
+                                                void* data = NULL);
+   virtual GFXPrimitiveBuffer *allocPrimitiveBuffer( U32 numIndices, U32 numPrimitives, GFXBufferType bufferType, void* data = NULL );
    
    // NOTE: The GL device doesn't need a vertex declaration at
    // this time, but we need to return something to keep the system

+ 1 - 0
Engine/source/gfx/gl/gfxGLEnumTranslate.cpp

@@ -45,6 +45,7 @@ void GFXGLEnumTranslate::init()
    GFXGLBufferType[GFXBufferTypeStatic] = GL_STATIC_DRAW;
    GFXGLBufferType[GFXBufferTypeDynamic] = GL_DYNAMIC_DRAW;
    GFXGLBufferType[GFXBufferTypeVolatile] = GL_STREAM_DRAW;
+   GFXGLBufferType[GFXBufferTypeImmutable] = GL_STATIC_DRAW;
 
    // Primitives
    GFXGLPrimType[GFXPointList] = GL_POINTS;

+ 4 - 8
Engine/source/renderInstance/renderParticleMgr.cpp

@@ -338,14 +338,10 @@ void RenderParticleMgr::render( SceneRenderState *state )
 void RenderParticleMgr::_initGFXResources()
 {
    // Screen quad
-   U16 *prims = NULL;
-   mScreenQuadPrimBuff.set(GFX, 4, 2, GFXBufferTypeStatic);
-   mScreenQuadPrimBuff.lock(&prims);
-   (*prims++) = 0;
-   (*prims++) = 1;
-   (*prims++) = 2;
-   (*prims++) = 3;
-   mScreenQuadPrimBuff.unlock();
+   U16 prims [] = {
+      0, 1, 2, 3,
+   };
+   mScreenQuadPrimBuff.immutable(GFX, 4, 2, prims);
 
    mScreenQuadVertBuff.set(GFX, 4, GFXBufferTypeStatic);
    CompositeQuadVert *verts = mScreenQuadVertBuff.lock();