LCOV - code coverage report
Current view: top level - source/renderer - VertexArray.h (source / functions) Hit Total Coverage
Test: 0 A.D. test coverage report Lines: 17 36 47.2 %
Date: 2023-01-19 00:18:29 Functions: 8 51 15.7 %

          Line data    Source code
       1             : /* Copyright (C) 2023 Wildfire Games.
       2             :  * This file is part of 0 A.D.
       3             :  *
       4             :  * 0 A.D. is free software: you can redistribute it and/or modify
       5             :  * it under the terms of the GNU General Public License as published by
       6             :  * the Free Software Foundation, either version 2 of the License, or
       7             :  * (at your option) any later version.
       8             :  *
       9             :  * 0 A.D. is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :  * GNU General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU General Public License
      15             :  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
      16             :  */
      17             : 
      18             : #ifndef INCLUDED_VERTEXARRAY
      19             : #define INCLUDED_VERTEXARRAY
      20             : 
      21             : #include "renderer/backend/Format.h"
      22             : #include "renderer/backend/IBuffer.h"
      23             : #include "renderer/backend/IDeviceCommandContext.h"
      24             : #include "renderer/VertexBufferManager.h"
      25             : 
      26             : #include <vector>
      27             : 
      28             : // Iterator
      29             : template<typename T>
      30             : class VertexArrayIterator
      31             : {
      32             : public:
      33             :     typedef T Type;
      34             : 
      35             : public:
      36           0 :     VertexArrayIterator() :
      37           0 :         m_Data(0), m_Stride(0)
      38             :     {
      39           0 :     }
      40             : 
      41           6 :     VertexArrayIterator(char* data, size_t stride) :
      42           6 :         m_Data(data), m_Stride(stride)
      43             :     {
      44           6 :     }
      45             : 
      46       36864 :     VertexArrayIterator(const VertexArrayIterator& rhs) :
      47       36864 :         m_Data(rhs.m_Data), m_Stride(rhs.m_Stride)
      48             :     {
      49       36864 :     }
      50             : 
      51           0 :     VertexArrayIterator& operator=(const VertexArrayIterator& rhs)
      52             :     {
      53           0 :         m_Data = rhs.m_Data;
      54           0 :         m_Stride = rhs.m_Stride;
      55           0 :         return *this;
      56             :     }
      57             : 
      58             :     // Accessors
      59       36864 :     T& operator*() const { return *(T*)m_Data; }
      60           0 :     T* operator->() const { return (T*)m_Data; }
      61           0 :     T& operator[](size_t idx) const { return *(T*)(m_Data + idx*m_Stride); }
      62             : 
      63             :     // Walking
      64           0 :     VertexArrayIterator& operator++()
      65             :     {
      66           0 :         m_Data += m_Stride;
      67           0 :         return *this;
      68             :     }
      69       36864 :     VertexArrayIterator operator++(int)
      70             :     {
      71       36864 :         VertexArrayIterator tmp = *this;
      72       36864 :         m_Data += m_Stride;
      73       36864 :         return tmp;
      74             :     }
      75             :     VertexArrayIterator& operator--()
      76             :     {
      77             :         m_Data -= m_Stride;
      78             :         return *this;
      79             :     }
      80             :     VertexArrayIterator operator--(int)
      81             :     {
      82             :         VertexArrayIterator tmp = *this;
      83             :         m_Data -= m_Stride;
      84             :         return tmp;
      85             :     }
      86             : 
      87             :     VertexArrayIterator& operator+=(ssize_t rhs)
      88             :     {
      89             :         m_Data += rhs*m_Stride;
      90             :         return *this;
      91             :     }
      92             :     VertexArrayIterator& operator-=(ssize_t rhs)
      93             :     {
      94             :         m_Data -= rhs*m_Stride;
      95             :         return *this;
      96             :     }
      97             : 
      98             :     VertexArrayIterator operator+(ssize_t rhs) const
      99             :     {
     100             :         VertexArrayIterator tmp = *this;
     101             :         tmp.m_Data += rhs*m_Stride;
     102             :         return tmp;
     103             :     }
     104             :     VertexArrayIterator operator-(ssize_t rhs) const
     105             :     {
     106             :         VertexArrayIterator tmp = *this;
     107             :         tmp.m_Data -= rhs*m_Stride;
     108             :         return tmp;
     109             :     }
     110             : 
     111             :     // Accessors for raw buffer data, for performance-critical code
     112           0 :     char* GetData() const
     113             :     {
     114           0 :         return m_Data;
     115             :     }
     116           0 :     size_t GetStride() const
     117             :     {
     118           0 :         return m_Stride;
     119             :     }
     120             : 
     121             : private:
     122             :     char* m_Data;
     123             :     size_t m_Stride;
     124             : };
     125             : 
     126             : 
     127             : // Manage a vertex array with a runtime-determined set of attributes.
     128             : //
     129             : // Purpose: Different rendering paths sometimes require different sets of
     130             : // attributes (e.g. normal vector vs. color data), which is difficult to
     131             : // support with hardcoded vertex structures.
     132             : // This class chooses the vertex layout at runtime, based on the attributes
     133             : // that are actually needed.
     134             : //
     135             : // Note that this class will not allocate any backend resources until one
     136             : // of the Upload functions is called.
     137             : class VertexArray
     138             : {
     139             : public:
     140             :     struct Attribute
     141             :     {
     142             :         Renderer::Backend::Format format = Renderer::Backend::Format::UNDEFINED;
     143             : 
     144             :         // Offset (in bytes) into a vertex structure (filled in by Layout())
     145             :         uint32_t offset = 0;
     146             : 
     147             :         VertexArray* vertexArray = nullptr;
     148             : 
     149          36 :         Attribute() {}
     150             : 
     151             :         // Get an iterator over the backing store for the given attribute that
     152             :         // initially points at the first vertex.
     153             :         // Supported types T: CVector3D, CVector4D, float[2], SColor4ub,
     154             :         // u16, u16[2], u8[4], short, short[2].
     155             :         // This function verifies at runtime that the requested type T matches
     156             :         // the attribute definition passed to AddAttribute().
     157             :         template<typename T>
     158             :         VertexArrayIterator<T> GetIterator() const;
     159             :     };
     160             : 
     161             : public:
     162             :     VertexArray(
     163             :         const Renderer::Backend::IBuffer::Type type, const bool dynamic);
     164             :     ~VertexArray();
     165             : 
     166             :     // Set the number of vertices stored in the array
     167             :     void SetNumberOfVertices(const size_t numberOfVertices);
     168             :     // Add vertex attributes
     169             :     void AddAttribute(Attribute* attr);
     170             : 
     171           0 :     size_t GetNumberOfVertices() const { return m_NumberOfVertices; }
     172           6 :     uint32_t GetStride() const { return m_Stride; }
     173             : 
     174             :     // Layout the vertex array format and create backing buffer in RAM.
     175             :     // You must call Layout() after changing the number of vertices or
     176             :     // attributes.
     177             :     // All vertex data is lost when a vertex array is re-layouted.
     178             :     void Layout();
     179             :     // (Re-)Upload the attributes of the vertex array from the backing store to
     180             :     // the underlying buffer.
     181             :     void Upload();
     182             :     // Make this vertex array's data available for the next series of calls to Bind
     183             :     void PrepareForRendering();
     184             : 
     185             :     void UploadIfNeeded(Renderer::Backend::IDeviceCommandContext* deviceCommandContext);
     186             : 
     187             :     // If you know for certain that you'll never have to change the data again,
     188             :     // call this to free some memory.
     189             :     void FreeBackingStore();
     190             : 
     191           0 :     Renderer::Backend::IBuffer* GetBuffer() { return m_VB ? m_VB->m_Owner->GetBuffer() : nullptr; }
     192             : 
     193           0 :     uint32_t GetOffset() const { return m_VB ? m_VB->m_Index : 0; }
     194             : 
     195             : private:
     196             :     void Free();
     197             : 
     198             :     template<typename T>
     199           6 :     VertexArrayIterator<T> MakeIterator(const Attribute* attr)
     200             :     {
     201           6 :         ENSURE(attr->format != Renderer::Backend::Format::UNDEFINED);
     202           6 :         return VertexArrayIterator<T>(m_BackingStore + attr->offset, m_Stride);
     203             :     }
     204             : 
     205             :     Renderer::Backend::IBuffer::Type m_Type;
     206             :     bool m_Dynamic;
     207             :     size_t m_NumberOfVertices;
     208             :     std::vector<Attribute*> m_Attributes;
     209             : 
     210             :     CVertexBufferManager::Handle m_VB;
     211             :     uint32_t m_Stride;
     212             :     char* m_BackingStore; // 16-byte aligned, to allow fast SSE access
     213             : };
     214             : 
     215             : /**
     216             :  * A VertexArray that is specialised to handle 16-bit array indices.
     217             :  * Call UploadIfNeeded() before use in Draw/DrawIndexed.
     218             :  */
     219           6 : class VertexIndexArray : public VertexArray
     220             : {
     221             : public:
     222             :     VertexIndexArray(const bool dynamic);
     223             : 
     224             :     /// Gets the iterator over the (only) attribute in this array, i.e. a u16.
     225             :     VertexArrayIterator<u16> GetIterator() const;
     226             : 
     227             : private:
     228             :     Attribute m_Attr;
     229             : };
     230             : 
     231             : #endif // INCLUDED_VERTEXARRAY

Generated by: LCOV version 1.13