浏览代码

Use a memory pool in OGLGraphics for discard lock buffers.
Include file reordering.

Lasse Öörni 14 年之前
父节点
当前提交
90596a064a

+ 1 - 1
Engine/Audio/Audio.h

@@ -23,12 +23,12 @@
 
 #pragma once
 
+#include "ArrayPtr.h"
 #include "AudioDefs.h"
 #include "Mutex.h"
 #include "Object.h"
 #include "Quaternion.h"
 #include "Thread.h"
-#include "ArrayPtr.h"
 
 class AudioImpl;
 class Sound;

+ 1 - 1
Engine/Audio/Sound.h

@@ -23,8 +23,8 @@
 
 #pragma once
 
-#include "Resource.h"
 #include "ArrayPtr.h"
+#include "Resource.h"
 
 /// %Sound resource.
 class Sound : public Resource

+ 1 - 1
Engine/Graphics/Geometry.h

@@ -23,9 +23,9 @@
 
 #pragma once
 
+#include "ArrayPtr.h"
 #include "GraphicsDefs.h"
 #include "Object.h"
-#include "ArrayPtr.h"
 
 class IndexBuffer;
 class Ray;

+ 1 - 1
Engine/Graphics/Model.h

@@ -23,11 +23,11 @@
 
 #pragma once
 
+#include "ArrayPtr.h"
 #include "BoundingBox.h"
 #include "Skeleton.h"
 #include "Resource.h"
 #include "Ptr.h"
-#include "ArrayPtr.h"
 
 class Geometry;
 class IndexBuffer;

+ 1 - 1
Engine/Graphics/OcclusionBuffer.h

@@ -23,10 +23,10 @@
 
 #pragma once
 
+#include "ArrayPtr.h"
 #include "Frustum.h"
 #include "Object.h"
 #include "GraphicsDefs.h"
-#include "ArrayPtr.h"
 
 class BoundingBox;
 class Camera;

+ 48 - 0
Engine/Graphics/OpenGL/OGLGraphics.cpp

@@ -46,6 +46,7 @@
 #include "ShaderProgram.h"
 #include "ShaderVariation.h"
 #include "Skybox.h"
+#include "StringUtils.h"
 #include "Technique.h"
 #include "Texture2D.h"
 #include "TextureCube.h"
@@ -1711,6 +1712,53 @@ void Graphics::RemoveGPUObject(GPUObject* object)
         gpuObjects_.Erase(i);
 }
 
+void* Graphics::ReserveDiscardLockBuffer(unsigned size)
+{
+    // First check for a free buffer that is large enough
+    for (Vector<DiscardLockBuffer>::Iterator i = discardLockBuffers_.Begin(); i != discardLockBuffers_.End(); ++i)
+    {
+        if (!i->reserved_ && i->size_ >= size)
+        {
+            i->reserved_ = true;
+            return i->data_.Get();
+        }
+    }
+    
+    // Then check if a free buffer can be resized
+    for (Vector<DiscardLockBuffer>::Iterator i = discardLockBuffers_.Begin(); i != discardLockBuffers_.End(); ++i)
+    {
+        if (!i->reserved_)
+        {
+            i->data_ = new unsigned char[size];
+            i->size_ = size;
+            i->reserved_ = true;
+            return i->data_.Get();
+        }
+    }
+    
+    // Finally allocate a new buffer
+    DiscardLockBuffer newBuffer;
+    newBuffer.data_ = new unsigned char[size];
+    newBuffer.size_ = size;
+    newBuffer.reserved_ = true;
+    discardLockBuffers_.Push(newBuffer);
+    return newBuffer.data_.Get();
+}
+
+void Graphics::FreeDiscardLockBuffer(void* buffer)
+{
+    for (Vector<DiscardLockBuffer>::Iterator i = discardLockBuffers_.Begin(); i != discardLockBuffers_.End(); ++i)
+    {
+        if (i->reserved_ && i->data_.Get() == buffer)
+        {
+            i->reserved_ = false;
+            return;
+        }
+    }
+    
+    LOGWARNING("Reserved discard lock buffer " + ToStringHex((unsigned)buffer) + " not found");
+}
+
 unsigned Graphics::GetAlphaFormat()
 {
     return GL_ALPHA;

+ 26 - 2
Engine/Graphics/OpenGL/OGLGraphics.h

@@ -23,12 +23,13 @@
 
 #pragma once
 
+#include "ArrayPtr.h"
 #include "Color.h"
+#include "GraphicsDefs.h"
 #include "HashMap.h"
 #include "Matrix3x4.h"
 #include "Object.h"
 #include "Rect.h"
-#include "GraphicsDefs.h"
 
 class Image;
 class IndexBuffer;
@@ -51,6 +52,23 @@ typedef Map<Pair<ShaderVariation*, ShaderVariation*>, SharedPtr<ShaderProgram> >
 
 static const unsigned NUM_SCREEN_BUFFERS = 2;
 
+/// CPU-side buffer for VBO discard locking.
+struct DiscardLockBuffer
+{
+    DiscardLockBuffer() :
+        size_(0),
+        reserved_(false)
+    {
+    }
+    
+    /// Buffer data.
+    SharedArrayPtr<unsigned char> data_;
+    /// Data size.
+    unsigned size_;
+    /// Reserved flag.
+    bool reserved_;
+};
+
 /// %Graphics subsystem. Manages the application window, rendering state and GPU resources.
 class Graphics : public Object
 {
@@ -304,7 +322,11 @@ public:
     void AddGPUObject(GPUObject* object);
     /// Remove a GPU object. Called by GPUObject.
     void RemoveGPUObject(GPUObject* object);
-
+    /// Reserve a CPU side discard locking buffer.
+    void* ReserveDiscardLockBuffer(unsigned size);
+    /// Free a CPU side discard locking buffer.
+    void FreeDiscardLockBuffer(void* buffer);
+    
     /// Return the API-specific alpha texture format.
     static unsigned GetAlphaFormat();
     /// Return the API-specific luminance texture format.
@@ -354,6 +376,8 @@ private:
     unsigned numBatches_;
     /// GPU objects.
     Vector<GPUObject*> gpuObjects_;
+    /// Discard lock buffers.
+    Vector<DiscardLockBuffer> discardLockBuffers_;
     /// Shadow map depth texture format.
     unsigned shadowMapFormat_;
     /// Shadow map 24-bit depth texture format.

+ 14 - 14
Engine/Graphics/OpenGL/OGLIndexBuffer.cpp

@@ -37,9 +37,9 @@ OBJECTTYPESTATIC(IndexBuffer);
 IndexBuffer::IndexBuffer(Context* context) :
     Object(context),
     GPUObject(GetSubsystem<Graphics>()),
+    discardLockData_(0),
     indexCount_(0),
     indexSize_(0),
-    discardLockSize_(0),
     dynamic_(false),
     locked_(false),
     mapped_(false)
@@ -197,14 +197,9 @@ void* IndexBuffer::Lock(unsigned start, unsigned count, LockMode mode)
         // In discard mode, use a CPU side buffer to avoid stalling
         if (mode == LOCK_DISCARD)
         {
-            if (discardLockSize_ < count * indexSize_)
-            {
-                discardLockData_ = new unsigned char[count * indexSize_];
-                discardLockSize_ = count * indexSize_;
-            }
+            hwData = discardLockData_ = graphics_->ReserveDiscardLockBuffer(count * indexSize_);
             discardLockStart_ = start;
             discardLockCount_ = count;
-            hwData = discardLockData_.Get();
         }
         else
         {
@@ -237,15 +232,20 @@ void IndexBuffer::Unlock()
                 glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
                 mapped_ = false;
             }
-            else if (discardLockCount_ < indexCount_)
-            {
-                glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, discardLockStart_ * indexSize_, discardLockCount_ * indexSize_,
-                    discardLockData_.Get());
-            }
             else
             {
-                glBufferData(GL_ELEMENT_ARRAY_BUFFER, discardLockCount_ * indexSize_, discardLockData_.Get(), dynamic_ ?
-                    GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
+                if (discardLockCount_ < indexCount_)
+                {
+                    glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, discardLockStart_ * indexSize_, discardLockCount_ * indexSize_,
+                        discardLockData_);
+                }
+                else
+                {
+                    glBufferData(GL_ELEMENT_ARRAY_BUFFER, discardLockCount_ * indexSize_, discardLockData_, dynamic_ ?
+                        GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
+                }
+                graphics_->FreeDiscardLockBuffer(discardLockData_);
+                discardLockData_ = 0;
             }
         }
         locked_ = false;

+ 2 - 4
Engine/Graphics/OpenGL/OGLIndexBuffer.h

@@ -23,10 +23,10 @@
 
 #pragma once
 
+#include "ArrayPtr.h"
 #include "GPUObject.h"
 #include "Object.h"
 #include "GraphicsDefs.h"
-#include "ArrayPtr.h"
 
 /// Hardware index buffer.
 class IndexBuffer : public Object, public GPUObject
@@ -79,13 +79,11 @@ private:
     /// Save data when OpenGL context needs to be destroyed and recreated.
     SharedArrayPtr<unsigned char> saveData_;
     /// Memory area for discard locking.
-    SharedArrayPtr<unsigned char> discardLockData_;
+    void* discardLockData_;
     /// Number of indices.
     unsigned indexCount_;
     /// Index size.
     unsigned indexSize_;
-    /// Discard lock data size.
-    unsigned discardLockSize_;
     /// Discard lock range start.
     unsigned discardLockStart_;
     /// Discard lock vertex count.

+ 1 - 1
Engine/Graphics/OpenGL/OGLRenderSurface.h

@@ -23,8 +23,8 @@
 
 #pragma once
 
-#include "Rect.h"
 #include "GraphicsDefs.h"
+#include "Rect.h"
 #include "Ptr.h"
 
 class Camera;

+ 1 - 1
Engine/Graphics/OpenGL/OGLShaderVariation.h

@@ -23,10 +23,10 @@
 
 #pragma once
 
+#include "ArrayPtr.h"
 #include "GPUObject.h"
 #include "GraphicsDefs.h"
 #include "RefCounted.h"
-#include "ArrayPtr.h"
 
 class Shader;
 class ShaderProgram;

+ 2 - 2
Engine/Graphics/OpenGL/OGLTexture.h

@@ -23,12 +23,12 @@
 
 #pragma once
 
+#include "ArrayPtr.h"
 #include "Color.h"
 #include "GPUObject.h"
-#include "Image.h"
 #include "GraphicsDefs.h"
+#include "Image.h"
 #include "Resource.h"
-#include "ArrayPtr.h"
 
 static const int MAX_TEXTURE_QUALITY_LEVELS = 3;
 

+ 14 - 14
Engine/Graphics/OpenGL/OGLVertexBuffer.cpp

@@ -121,11 +121,11 @@ OBJECTTYPESTATIC(VertexBuffer);
 VertexBuffer::VertexBuffer(Context* context) :
     Object(context),
     GPUObject(GetSubsystem<Graphics>()),
+    discardLockData_(0),
     vertexCount_(0),
     elementMask_(0),
     morphRangeStart_(0),
     morphRangeCount_(0),
-    discardLockSize_(0),
     dynamic_(false),
     locked_(false),
     mapped_(false)
@@ -310,14 +310,9 @@ void* VertexBuffer::Lock(unsigned start, unsigned count, LockMode mode)
         // In discard mode, use a CPU side buffer to avoid stalling
         if (mode == LOCK_DISCARD)
         {
-            if (discardLockSize_ < count * vertexSize_)
-            {
-                discardLockData_ = new unsigned char[count * vertexSize_];
-                discardLockSize_ = count * vertexSize_;
-            }
+            hwData = discardLockData_ = graphics_->ReserveDiscardLockBuffer(count * vertexSize_);
             discardLockStart_ = start;
             discardLockCount_ = count;
-            hwData = discardLockData_.Get();
         }
         else
         {
@@ -348,15 +343,20 @@ void VertexBuffer::Unlock()
                 glUnmapBuffer(GL_ARRAY_BUFFER);
                 mapped_ = false;
             }
-            else if (discardLockCount_ < vertexCount_)
-            {
-                glBufferSubData(GL_ARRAY_BUFFER, discardLockStart_ * vertexSize_, discardLockCount_ * vertexSize_,
-                    discardLockData_.Get());
-            }
             else
             {
-                glBufferData(GL_ARRAY_BUFFER, discardLockCount_ * vertexSize_, discardLockData_.Get(), dynamic_ ?
-                    GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
+                if (discardLockCount_ < vertexCount_)
+                {
+                    glBufferSubData(GL_ARRAY_BUFFER, discardLockStart_ * vertexSize_, discardLockCount_ * vertexSize_,
+                        discardLockData_);
+                }
+                else
+                {
+                    glBufferData(GL_ARRAY_BUFFER, discardLockCount_ * vertexSize_, discardLockData_, dynamic_ ?
+                        GL_DYNAMIC_DRAW : GL_STATIC_DRAW);
+                }
+                graphics_->FreeDiscardLockBuffer(discardLockData_);
+                discardLockData_ = 0;
             }
         }
         locked_ = false;

+ 2 - 4
Engine/Graphics/OpenGL/OGLVertexBuffer.h

@@ -23,9 +23,9 @@
 
 #pragma once
 
+#include "ArrayPtr.h"
 #include "GPUObject.h"
 #include "GraphicsDefs.h"
-#include "ArrayPtr.h"
 
 /// Hardware vertex buffer.
 class VertexBuffer : public Object, public GPUObject
@@ -114,7 +114,7 @@ private:
     /// Save data when OpenGL context needs to be destroyed and recreated.
     SharedArrayPtr<unsigned char> saveData_;
     /// Memory area for discard locking.
-    SharedArrayPtr<unsigned char> discardLockData_;
+    void* discardLockData_;
     /// Number of vertices.
     unsigned vertexCount_;
     /// Vertex size.
@@ -127,8 +127,6 @@ private:
     unsigned morphRangeStart_;
     /// Number of vertices in the morph range.
     unsigned morphRangeCount_;
-    /// Discard lock data size.
-    unsigned discardLockSize_;
     /// Discard lock range start.
     unsigned discardLockStart_;
     /// Discard lock vertex count.

+ 1 - 1
Engine/IO/FileSystem.cpp

@@ -22,11 +22,11 @@
 //
 
 #include "Precompiled.h"
+#include "ArrayPtr.h"
 #include "Context.h"
 #include "File.h"
 #include "FileSystem.h"
 #include "Log.h"
-#include "ArrayPtr.h"
 
 #include <cstdio>
 #include <cstring>

+ 1 - 1
Engine/Physics/CollisionShape.h

@@ -24,10 +24,10 @@
 #pragma once
 
 #include "BoundingBox.h"
+#include "ArrayPtr.h"
 #include "Component.h"
 #include "Quaternion.h"
 #include "PhysicsDefs.h"
-#include "ArrayPtr.h"
 
 class DebugRenderer;
 class Geometry;

+ 1 - 1
Engine/Resource/Image.h

@@ -23,8 +23,8 @@
 
 #pragma once
 
-#include "Resource.h"
 #include "ArrayPtr.h"
+#include "Resource.h"
 
 /// Supported compressed image formats.
 enum CompressedFormat

+ 1 - 1
Engine/Resource/XMLFile.cpp

@@ -22,10 +22,10 @@
 //
 
 #include "Precompiled.h"
+#include "ArrayPtr.h"
 #include "Context.h"
 #include "File.h"
 #include "Log.h"
-#include "ArrayPtr.h"
 #include "XMLFile.h"
 
 #include <tinyxml.h>

+ 1 - 1
Engine/Script/ScriptFile.cpp

@@ -22,6 +22,7 @@
 //
 
 #include "Precompiled.h"
+#include "ArrayPtr.h"
 #include "Context.h"
 #include "FileSystem.h"
 #include "Log.h"
@@ -30,7 +31,6 @@
 #include "Script.h"
 #include "ScriptFile.h"
 #include "ScriptInstance.h"
-#include "ArrayPtr.h"
 
 #include <angelscript.h>
 #include <cstring>

+ 1 - 1
Engine/UI/Font.h

@@ -23,8 +23,8 @@
 
 #pragma once
 
-#include "Resource.h"
 #include "ArrayPtr.h"
+#include "Resource.h"
 
 class Graphics;
 class Texture;

+ 1 - 1
Engine/UI/UIBatch.h

@@ -24,8 +24,8 @@
 #pragma once
 
 #include "Color.h"
-#include "Rect.h"
 #include "GraphicsDefs.h"
+#include "Rect.h"
 
 class PixelShader;
 class Graphics;

+ 1 - 1
Tools/PackageTool/PackageTool.cpp

@@ -22,10 +22,10 @@
 //
 
 #include "Context.h"
+#include "ArrayPtr.h"
 #include "File.h"
 #include "FileSystem.h"
 #include "ProcessUtils.h"
-#include "ArrayPtr.h"
 
 #include <cstdio>
 #include <cstdlib>

+ 1 - 1
Tools/RampGenerator/RampGenerator.cpp

@@ -21,9 +21,9 @@
 // THE SOFTWARE.
 //
 
+#include "ArrayPtr.h"
 #include "MathDefs.h"
 #include "ProcessUtils.h"
-#include "ArrayPtr.h"
 #include "StringUtils.h"
 
 #include <stb_image.h>