mirror of https://github.com/AxioDL/metaforce.git
Move Vertex/Uniform buffer pools to hecl
This commit is contained in:
parent
e9dc6787ce
commit
9162db2dcf
|
@ -60,9 +60,7 @@ list(APPEND SPECTER_HEADERS
|
||||||
include/specter/FileBrowser.hpp
|
include/specter/FileBrowser.hpp
|
||||||
include/specter/Icon.hpp
|
include/specter/Icon.hpp
|
||||||
include/specter/FontCache.hpp
|
include/specter/FontCache.hpp
|
||||||
include/specter/Translator.hpp
|
include/specter/Translator.hpp)
|
||||||
include/specter/UniformBufferPool.hpp
|
|
||||||
include/specter/VertexBufferPool.hpp)
|
|
||||||
|
|
||||||
atdna(atdna_FontCache.cpp include/specter/FontCache.hpp)
|
atdna(atdna_FontCache.cpp include/specter/FontCache.hpp)
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ private:
|
||||||
zeus::CColor m_line2Clear;
|
zeus::CColor m_line2Clear;
|
||||||
|
|
||||||
ViewBlock m_viewBlock;
|
ViewBlock m_viewBlock;
|
||||||
std::experimental::optional<UniformBufferPool<ViewBlock>::Token> m_viewBlockBuf;
|
std::experimental::optional<hecl::UniformBufferPool<ViewBlock>::Token> m_viewBlockBuf;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
|
|
|
@ -56,7 +56,7 @@ class RootView : public View
|
||||||
|
|
||||||
VertexBufferBindingSolid m_vertsBinding;
|
VertexBufferBindingSolid m_vertsBinding;
|
||||||
ViewBlock m_viewBlock;
|
ViewBlock m_viewBlock;
|
||||||
std::experimental::optional<UniformBufferPool<ViewBlock>::Token> m_viewVertBlockBuf;
|
std::experimental::optional<hecl::UniformBufferPool<ViewBlock>::Token> m_viewVertBlockBuf;
|
||||||
SolidShaderVert m_verts[32];
|
SolidShaderVert m_verts[32];
|
||||||
void setArrowVerts(const boo::SWindowRect& rect, SplitView::ArrowDir dir);
|
void setArrowVerts(const boo::SWindowRect& rect, SplitView::ArrowDir dir);
|
||||||
void setLineVerts(const boo::SWindowRect& rect, float split, SplitView::Axis axis);
|
void setLineVerts(const boo::SWindowRect& rect, float split, SplitView::Axis axis);
|
||||||
|
|
|
@ -43,7 +43,7 @@ private:
|
||||||
|
|
||||||
ViewChild<View*> m_views[2];
|
ViewChild<View*> m_views[2];
|
||||||
ViewBlock m_splitBlock;
|
ViewBlock m_splitBlock;
|
||||||
std::experimental::optional<UniformBufferPool<ViewBlock>::Token> m_splitBlockBuf;
|
std::experimental::optional<hecl::UniformBufferPool<ViewBlock>::Token> m_splitBlockBuf;
|
||||||
TexShaderVert m_splitVerts[4];
|
TexShaderVert m_splitVerts[4];
|
||||||
|
|
||||||
int m_clearanceA, m_clearanceB;
|
int m_clearanceA, m_clearanceB;
|
||||||
|
|
|
@ -44,7 +44,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
size_t m_capacity;
|
size_t m_capacity;
|
||||||
std::experimental::optional<VertexBufferPool<RenderGlyph>::Token> m_glyphBuf;
|
std::experimental::optional<hecl::VertexBufferPool<RenderGlyph>::Token> m_glyphBuf;
|
||||||
boo::IVertexFormat* m_vtxFmt = nullptr; /* OpenGL only */
|
boo::IVertexFormat* m_vtxFmt = nullptr; /* OpenGL only */
|
||||||
boo::IShaderDataBinding* m_shaderBinding;
|
boo::IShaderDataBinding* m_shaderBinding;
|
||||||
const FontAtlas& m_fontAtlas;
|
const FontAtlas& m_fontAtlas;
|
||||||
|
@ -63,7 +63,7 @@ public:
|
||||||
friend class TextView;
|
friend class TextView;
|
||||||
friend class MultiLineTextView;
|
friend class MultiLineTextView;
|
||||||
|
|
||||||
VertexBufferPool<RenderGlyph> m_glyphPool;
|
hecl::VertexBufferPool<RenderGlyph> m_glyphPool;
|
||||||
|
|
||||||
void updateBuffers()
|
void updateBuffers()
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,7 +31,7 @@ private:
|
||||||
std::vector<std::vector<ViewChild<View*>>> m_children;
|
std::vector<std::vector<ViewChild<View*>>> m_children;
|
||||||
|
|
||||||
ViewBlock m_tbBlock;
|
ViewBlock m_tbBlock;
|
||||||
std::experimental::optional<UniformBufferPool<ViewBlock>::Token> m_tbBlockBuf;
|
std::experimental::optional<hecl::UniformBufferPool<ViewBlock>::Token> m_tbBlockBuf;
|
||||||
TexShaderVert m_tbVerts[10];
|
TexShaderVert m_tbVerts[10];
|
||||||
int m_nomGauge = 25;
|
int m_nomGauge = 25;
|
||||||
int m_padding = 10;
|
int m_padding = 10;
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace specter
|
||||||
class Tooltip : public View
|
class Tooltip : public View
|
||||||
{
|
{
|
||||||
ViewBlock m_ttBlock;
|
ViewBlock m_ttBlock;
|
||||||
std::experimental::optional<UniformBufferPool<ViewBlock>::Token> m_ttBlockBuf;
|
std::experimental::optional<hecl::UniformBufferPool<ViewBlock>::Token> m_ttBlockBuf;
|
||||||
SolidShaderVert m_ttVerts[16];
|
SolidShaderVert m_ttVerts[16];
|
||||||
int m_nomWidth = 25;
|
int m_nomWidth = 25;
|
||||||
int m_nomHeight = 25;
|
int m_nomHeight = 25;
|
||||||
|
|
|
@ -1,186 +0,0 @@
|
||||||
#ifndef SPECTER_UNIFORMBUFFERPOOL_HPP
|
|
||||||
#define SPECTER_UNIFORMBUFFERPOOL_HPP
|
|
||||||
|
|
||||||
#include <boo/boo.hpp>
|
|
||||||
#include <hecl/BitVector.hpp>
|
|
||||||
#include <vector>
|
|
||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
namespace specter
|
|
||||||
{
|
|
||||||
|
|
||||||
#define SPECTER_UBUFPOOL_ALLOCATION_BLOCK 262144
|
|
||||||
|
|
||||||
/** This class provides a uniform structure for packing instanced uniform-buffer
|
|
||||||
* data with consistent stride into a vector of 256K 'Buckets'.
|
|
||||||
*
|
|
||||||
* This results in a space-efficient way of managing GPU data of things like UI
|
|
||||||
* widgets. These can potentially have numerous binding instances, so this avoids
|
|
||||||
* allocating a full GPU buffer object for each. */
|
|
||||||
template <typename UniformStruct>
|
|
||||||
class UniformBufferPool
|
|
||||||
{
|
|
||||||
/* Resolve div_t type using ssize_t as basis */
|
|
||||||
#if _WIN32
|
|
||||||
using IndexTp = SSIZE_T;
|
|
||||||
#else
|
|
||||||
using IndexTp = ssize_t;
|
|
||||||
#endif
|
|
||||||
struct InvalidTp {};
|
|
||||||
using DivTp = std::conditional_t<std::is_same<IndexTp, long long>::value, std::lldiv_t,
|
|
||||||
std::conditional_t<std::is_same<IndexTp, long>::value, std::ldiv_t,
|
|
||||||
std::conditional_t<std::is_same<IndexTp, int>::value, std::div_t, InvalidTp>>>;
|
|
||||||
static_assert(!std::is_same<DivTp, InvalidTp>::value, "unsupported IndexTp for DivTp resolution");
|
|
||||||
|
|
||||||
/** Size of single element, rounded up to 256-multiple */
|
|
||||||
static constexpr IndexTp m_stride = ROUND_UP_256(sizeof(UniformStruct));
|
|
||||||
static_assert(m_stride <= SPECTER_UBUFPOOL_ALLOCATION_BLOCK, "Stride too large for uniform pool");
|
|
||||||
|
|
||||||
/** Number of rounded elements per 256K bucket */
|
|
||||||
static constexpr IndexTp m_countPerBucket = SPECTER_UBUFPOOL_ALLOCATION_BLOCK / m_stride;
|
|
||||||
|
|
||||||
/** Buffer size per bucket (ideally 256K) */
|
|
||||||
static constexpr IndexTp m_sizePerBucket = m_stride * m_countPerBucket;
|
|
||||||
|
|
||||||
/** BitVector indicating free allocation blocks */
|
|
||||||
hecl::llvm::BitVector m_freeBlocks;
|
|
||||||
|
|
||||||
/** Efficient way to get bucket and block simultaneously */
|
|
||||||
DivTp getBucketDiv(IndexTp idx) const { return std::div(idx, m_countPerBucket); }
|
|
||||||
|
|
||||||
/** Buffer pool token */
|
|
||||||
boo::GraphicsBufferPoolToken m_token;
|
|
||||||
|
|
||||||
/** Private bucket info */
|
|
||||||
struct Bucket
|
|
||||||
{
|
|
||||||
boo::IGraphicsBufferD* buffer;
|
|
||||||
uint8_t* cpuBuffer = nullptr;
|
|
||||||
size_t useCount = 0;
|
|
||||||
bool dirty = false;
|
|
||||||
Bucket() = default;
|
|
||||||
Bucket(const Bucket& other) = delete;
|
|
||||||
Bucket& operator=(const Bucket& other) = delete;
|
|
||||||
Bucket(Bucket&& other) = default;
|
|
||||||
Bucket& operator=(Bucket&& other) = default;
|
|
||||||
|
|
||||||
void updateBuffer()
|
|
||||||
{
|
|
||||||
if (buffer)
|
|
||||||
buffer->unmap();
|
|
||||||
cpuBuffer = nullptr;
|
|
||||||
dirty = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void increment(UniformBufferPool& pool)
|
|
||||||
{
|
|
||||||
if (!useCount)
|
|
||||||
buffer = pool.m_token.newPoolBuffer(boo::BufferUse::Uniform,
|
|
||||||
pool.m_stride, pool.m_countPerBucket);
|
|
||||||
++useCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
void decrement(UniformBufferPool& pool)
|
|
||||||
{
|
|
||||||
--useCount;
|
|
||||||
if (!useCount)
|
|
||||||
{
|
|
||||||
pool.m_token.deletePoolBuffer(buffer);
|
|
||||||
buffer = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
std::vector<Bucket> m_buckets;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/** User block-owning token */
|
|
||||||
class Token
|
|
||||||
{
|
|
||||||
friend class UniformBufferPool;
|
|
||||||
UniformBufferPool& m_pool;
|
|
||||||
IndexTp m_index;
|
|
||||||
DivTp m_div;
|
|
||||||
Token(UniformBufferPool& pool)
|
|
||||||
: m_pool(pool)
|
|
||||||
{
|
|
||||||
auto& freeSpaces = pool.m_freeBlocks;
|
|
||||||
auto& buckets = pool.m_buckets;
|
|
||||||
int idx = freeSpaces.find_first();
|
|
||||||
if (idx == -1)
|
|
||||||
{
|
|
||||||
buckets.emplace_back();
|
|
||||||
m_index = freeSpaces.size();
|
|
||||||
freeSpaces.resize(freeSpaces.size() + pool.m_countPerBucket, true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_index = idx;
|
|
||||||
}
|
|
||||||
freeSpaces.reset(m_index);
|
|
||||||
m_div = pool.getBucketDiv(m_index);
|
|
||||||
|
|
||||||
Bucket& bucket = m_pool.m_buckets[m_div.quot];
|
|
||||||
bucket.increment(m_pool);
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
Token(const Token& other) = delete;
|
|
||||||
Token& operator=(const Token& other) = delete;
|
|
||||||
Token& operator=(Token&& other) = delete;
|
|
||||||
Token(Token&& other)
|
|
||||||
: m_pool(other.m_pool), m_index(other.m_index),
|
|
||||||
m_div(other.m_div)
|
|
||||||
{
|
|
||||||
other.m_index = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
~Token()
|
|
||||||
{
|
|
||||||
if (m_index != -1)
|
|
||||||
{
|
|
||||||
m_pool.m_freeBlocks.set(m_index);
|
|
||||||
Bucket& bucket = m_pool.m_buckets[m_div.quot];
|
|
||||||
bucket.decrement(m_pool);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UniformStruct& access()
|
|
||||||
{
|
|
||||||
Bucket& bucket = m_pool.m_buckets[m_div.quot];
|
|
||||||
if (!bucket.cpuBuffer)
|
|
||||||
bucket.cpuBuffer = reinterpret_cast<uint8_t*>(bucket.buffer->map(m_sizePerBucket));
|
|
||||||
bucket.dirty = true;
|
|
||||||
return reinterpret_cast<UniformStruct&>(bucket.cpuBuffer[m_div.rem * m_pool.m_stride]);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<boo::IGraphicsBufferD*, IndexTp> getBufferInfo() const
|
|
||||||
{
|
|
||||||
Bucket& bucket = m_pool.m_buckets[m_div.quot];
|
|
||||||
return {bucket.buffer, m_div.rem * m_pool.m_stride};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
UniformBufferPool() = default;
|
|
||||||
UniformBufferPool(const UniformBufferPool& other) = delete;
|
|
||||||
UniformBufferPool& operator=(const UniformBufferPool& other) = delete;
|
|
||||||
|
|
||||||
/** Load dirty buffer data into GPU */
|
|
||||||
void updateBuffers()
|
|
||||||
{
|
|
||||||
for (Bucket& bucket : m_buckets)
|
|
||||||
if (bucket.dirty)
|
|
||||||
bucket.updateBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Allocate free block into client-owned Token */
|
|
||||||
Token allocateBlock(boo::IGraphicsDataFactory* factory)
|
|
||||||
{
|
|
||||||
if (!m_token)
|
|
||||||
m_token = factory->newBufferPool();
|
|
||||||
return Token(*this);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // SPECTER_UNIFORMBUFFERPOOL_HPP
|
|
|
@ -1,189 +0,0 @@
|
||||||
#ifndef SPECTER_VERTEXBUFFERPOOL_HPP
|
|
||||||
#define SPECTER_VERTEXBUFFERPOOL_HPP
|
|
||||||
|
|
||||||
#include <boo/boo.hpp>
|
|
||||||
#include <hecl/BitVector.hpp>
|
|
||||||
#include <vector>
|
|
||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
namespace specter
|
|
||||||
{
|
|
||||||
|
|
||||||
#define SPECTER_VBUFPOOL_ALLOCATION_BLOCK 262144
|
|
||||||
|
|
||||||
/** This class provides a uniform structure for packing instanced vertex-buffer
|
|
||||||
* data with consistent stride into a vector of 256K 'Buckets'.
|
|
||||||
*
|
|
||||||
* This results in a space-efficient way of managing GPU data of things like UI
|
|
||||||
* widgets. These can potentially have numerous binding instances, so this avoids
|
|
||||||
* allocating a full GPU buffer object for each. */
|
|
||||||
template <typename VertStruct>
|
|
||||||
class VertexBufferPool
|
|
||||||
{
|
|
||||||
/* Resolve div_t type using ssize_t as basis */
|
|
||||||
#if _WIN32
|
|
||||||
using IndexTp = SSIZE_T;
|
|
||||||
#else
|
|
||||||
using IndexTp = ssize_t;
|
|
||||||
#endif
|
|
||||||
struct InvalidTp {};
|
|
||||||
using DivTp = std::conditional_t<std::is_same<IndexTp, long long>::value, std::lldiv_t,
|
|
||||||
std::conditional_t<std::is_same<IndexTp, long>::value, std::ldiv_t,
|
|
||||||
std::conditional_t<std::is_same<IndexTp, int>::value, std::div_t, InvalidTp>>>;
|
|
||||||
static_assert(!std::is_same<DivTp, InvalidTp>::value, "unsupported IndexTp for DivTp resolution");
|
|
||||||
|
|
||||||
/** Size of single element */
|
|
||||||
static constexpr IndexTp m_stride = sizeof(VertStruct);
|
|
||||||
static_assert(m_stride <= SPECTER_VBUFPOOL_ALLOCATION_BLOCK, "Stride too large for vertex pool");
|
|
||||||
|
|
||||||
/** Number of elements per 256K bucket */
|
|
||||||
static constexpr IndexTp m_countPerBucket = SPECTER_VBUFPOOL_ALLOCATION_BLOCK / m_stride;
|
|
||||||
|
|
||||||
/** Buffer size per bucket (ideally 256K) */
|
|
||||||
static constexpr IndexTp m_sizePerBucket = m_stride * m_countPerBucket;
|
|
||||||
|
|
||||||
/** BitVector indicating free allocation elements */
|
|
||||||
hecl::llvm::BitVector m_freeElements;
|
|
||||||
|
|
||||||
/** Efficient way to get bucket and element simultaneously */
|
|
||||||
DivTp getBucketDiv(IndexTp idx) const { return std::div(idx, m_countPerBucket); }
|
|
||||||
|
|
||||||
/** Buffer pool token */
|
|
||||||
boo::GraphicsBufferPoolToken m_token;
|
|
||||||
|
|
||||||
/** Private bucket info */
|
|
||||||
struct Bucket
|
|
||||||
{
|
|
||||||
boo::IGraphicsBufferD* buffer;
|
|
||||||
uint8_t* cpuBuffer = nullptr;
|
|
||||||
size_t useCount = 0;
|
|
||||||
bool dirty = false;
|
|
||||||
Bucket() = default;
|
|
||||||
Bucket(const Bucket& other) = delete;
|
|
||||||
Bucket& operator=(const Bucket& other) = delete;
|
|
||||||
Bucket(Bucket&& other) = default;
|
|
||||||
Bucket& operator=(Bucket&& other) = default;
|
|
||||||
|
|
||||||
void updateBuffer()
|
|
||||||
{
|
|
||||||
if (buffer)
|
|
||||||
buffer->unmap();
|
|
||||||
cpuBuffer = nullptr;
|
|
||||||
dirty = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void increment(VertexBufferPool& pool)
|
|
||||||
{
|
|
||||||
if (!useCount)
|
|
||||||
buffer = pool.m_token.newPoolBuffer(boo::BufferUse::Vertex,
|
|
||||||
pool.m_stride, pool.m_countPerBucket);
|
|
||||||
++useCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
void decrement(VertexBufferPool& pool)
|
|
||||||
{
|
|
||||||
--useCount;
|
|
||||||
if (!useCount)
|
|
||||||
{
|
|
||||||
pool.m_token.deletePoolBuffer(buffer);
|
|
||||||
buffer = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
std::vector<Bucket> m_buckets;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/** User element-owning token */
|
|
||||||
class Token
|
|
||||||
{
|
|
||||||
friend class VertexBufferPool;
|
|
||||||
VertexBufferPool& m_pool;
|
|
||||||
IndexTp m_index;
|
|
||||||
IndexTp m_count;
|
|
||||||
DivTp m_div;
|
|
||||||
Token(VertexBufferPool& pool, IndexTp count)
|
|
||||||
: m_pool(pool), m_count(count)
|
|
||||||
{
|
|
||||||
assert(count <= pool.m_countPerBucket && "unable to fit in bucket");
|
|
||||||
auto& freeSpaces = pool.m_freeElements;
|
|
||||||
auto& buckets = pool.m_buckets;
|
|
||||||
int idx = freeSpaces.find_first_contiguous(count, pool.m_countPerBucket);
|
|
||||||
if (idx == -1)
|
|
||||||
{
|
|
||||||
buckets.emplace_back();
|
|
||||||
m_index = freeSpaces.size();
|
|
||||||
freeSpaces.resize(freeSpaces.size() + pool.m_countPerBucket, true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_index = idx;
|
|
||||||
}
|
|
||||||
freeSpaces.reset(m_index, m_index + count);
|
|
||||||
m_div = pool.getBucketDiv(m_index);
|
|
||||||
|
|
||||||
Bucket& bucket = m_pool.m_buckets[m_div.quot];
|
|
||||||
bucket.increment(pool);
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
Token(const Token& other) = delete;
|
|
||||||
Token& operator=(const Token& other) = delete;
|
|
||||||
Token& operator=(Token&& other) = delete;
|
|
||||||
Token(Token&& other)
|
|
||||||
: m_pool(other.m_pool), m_index(other.m_index),
|
|
||||||
m_count(other.m_count), m_div(other.m_div)
|
|
||||||
{
|
|
||||||
other.m_index = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
~Token()
|
|
||||||
{
|
|
||||||
if (m_index != -1)
|
|
||||||
{
|
|
||||||
m_pool.m_freeElements.set(m_index, m_index + m_count);
|
|
||||||
Bucket& bucket = m_pool.m_buckets[m_div.quot];
|
|
||||||
bucket.decrement(m_pool);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VertStruct* access()
|
|
||||||
{
|
|
||||||
Bucket& bucket = m_pool.m_buckets[m_div.quot];
|
|
||||||
if (!bucket.cpuBuffer)
|
|
||||||
bucket.cpuBuffer = reinterpret_cast<uint8_t*>(bucket.buffer->map(m_sizePerBucket));
|
|
||||||
bucket.dirty = true;
|
|
||||||
return reinterpret_cast<VertStruct*>(&bucket.cpuBuffer[m_div.rem * m_pool.m_stride]);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<boo::IGraphicsBufferD*, IndexTp> getBufferInfo() const
|
|
||||||
{
|
|
||||||
Bucket& bucket = m_pool.m_buckets[m_div.quot];
|
|
||||||
return {bucket.buffer, m_div.rem};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
VertexBufferPool() = default;
|
|
||||||
VertexBufferPool(const VertexBufferPool& other) = delete;
|
|
||||||
VertexBufferPool& operator=(const VertexBufferPool& other) = delete;
|
|
||||||
|
|
||||||
/** Load dirty buffer data into GPU */
|
|
||||||
void updateBuffers()
|
|
||||||
{
|
|
||||||
for (Bucket& bucket : m_buckets)
|
|
||||||
if (bucket.dirty)
|
|
||||||
bucket.updateBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Allocate free block into client-owned Token */
|
|
||||||
Token allocateBlock(boo::IGraphicsDataFactory* factory, IndexTp count)
|
|
||||||
{
|
|
||||||
if (!m_token)
|
|
||||||
m_token = factory->newBufferPool();
|
|
||||||
return Token(*this, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr IndexTp bucketCapacity() { return m_countPerBucket; }
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // SPECTER_VERTEXBUFFERPOOL_HPP
|
|
|
@ -8,8 +8,8 @@
|
||||||
#include "zeus/CTransform.hpp"
|
#include "zeus/CTransform.hpp"
|
||||||
#include "zeus/CColor.hpp"
|
#include "zeus/CColor.hpp"
|
||||||
#include "hecl/CVar.hpp"
|
#include "hecl/CVar.hpp"
|
||||||
#include "UniformBufferPool.hpp"
|
#include "hecl/UniformBufferPool.hpp"
|
||||||
#include "VertexBufferPool.hpp"
|
#include "hecl/VertexBufferPool.hpp"
|
||||||
|
|
||||||
#include <boo/graphicsdev/GL.hpp>
|
#include <boo/graphicsdev/GL.hpp>
|
||||||
#include <boo/graphicsdev/D3D.hpp>
|
#include <boo/graphicsdev/D3D.hpp>
|
||||||
|
@ -110,7 +110,7 @@ public:
|
||||||
template <typename VertStruct>
|
template <typename VertStruct>
|
||||||
struct VertexBufferBinding
|
struct VertexBufferBinding
|
||||||
{
|
{
|
||||||
std::experimental::optional<typename VertexBufferPool<VertStruct>::Token> m_vertsBuf;
|
std::experimental::optional<typename hecl::VertexBufferPool<VertStruct>::Token> m_vertsBuf;
|
||||||
boo::IVertexFormat* m_vtxFmt = nullptr; /* OpenGL only */
|
boo::IVertexFormat* m_vtxFmt = nullptr; /* OpenGL only */
|
||||||
boo::IShaderDataBinding* m_shaderBinding = nullptr;
|
boo::IShaderDataBinding* m_shaderBinding = nullptr;
|
||||||
|
|
||||||
|
@ -143,13 +143,13 @@ public:
|
||||||
{
|
{
|
||||||
void init(boo::IGraphicsDataFactory::Context& ctx,
|
void init(boo::IGraphicsDataFactory::Context& ctx,
|
||||||
ViewResources& res, size_t count,
|
ViewResources& res, size_t count,
|
||||||
const UniformBufferPool<ViewBlock>::Token& viewBlockBuf);
|
const hecl::UniformBufferPool<ViewBlock>::Token& viewBlockBuf);
|
||||||
};
|
};
|
||||||
struct VertexBufferBindingTex : VertexBufferBinding<TexShaderVert>
|
struct VertexBufferBindingTex : VertexBufferBinding<TexShaderVert>
|
||||||
{
|
{
|
||||||
void init(boo::IGraphicsDataFactory::Context& ctx,
|
void init(boo::IGraphicsDataFactory::Context& ctx,
|
||||||
ViewResources& res, size_t count,
|
ViewResources& res, size_t count,
|
||||||
const UniformBufferPool<ViewBlock>::Token& viewBlockBuf,
|
const hecl::UniformBufferPool<ViewBlock>::Token& viewBlockBuf,
|
||||||
boo::ITexture* texture);
|
boo::ITexture* texture);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -184,14 +184,14 @@ protected:
|
||||||
" float4x4 mv;\n"\
|
" float4x4 mv;\n"\
|
||||||
" float4 mulColor;\n"\
|
" float4 mulColor;\n"\
|
||||||
"};\n"
|
"};\n"
|
||||||
std::experimental::optional<UniformBufferPool<ViewBlock>::Token> m_viewVertBlockBuf;
|
std::experimental::optional<hecl::UniformBufferPool<ViewBlock>::Token> m_viewVertBlockBuf;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct Resources
|
struct Resources
|
||||||
{
|
{
|
||||||
UniformBufferPool<ViewBlock> m_bufPool;
|
hecl::UniformBufferPool<ViewBlock> m_bufPool;
|
||||||
VertexBufferPool<SolidShaderVert> m_solidPool;
|
hecl::VertexBufferPool<SolidShaderVert> m_solidPool;
|
||||||
VertexBufferPool<TexShaderVert> m_texPool;
|
hecl::VertexBufferPool<TexShaderVert> m_texPool;
|
||||||
|
|
||||||
void updateBuffers()
|
void updateBuffers()
|
||||||
{
|
{
|
||||||
|
|
|
@ -365,9 +365,9 @@ TextView::TextView(ViewResources& res,
|
||||||
m_fontAtlas(font),
|
m_fontAtlas(font),
|
||||||
m_align(align)
|
m_align(align)
|
||||||
{
|
{
|
||||||
if (size_t(VertexBufferPool<RenderGlyph>::bucketCapacity()) < capacity)
|
if (size_t(hecl::VertexBufferPool<RenderGlyph>::bucketCapacity()) < capacity)
|
||||||
Log.report(logvisor::Fatal, "bucket overflow [%" PRISize "/%" PRISize "]",
|
Log.report(logvisor::Fatal, "bucket overflow [%" PRISize "/%" PRISize "]",
|
||||||
capacity, VertexBufferPool<RenderGlyph>::bucketCapacity());
|
capacity, hecl::VertexBufferPool<RenderGlyph>::bucketCapacity());
|
||||||
|
|
||||||
_commitResources(0);
|
_commitResources(0);
|
||||||
}
|
}
|
||||||
|
@ -408,7 +408,7 @@ int TextView::DoKern(FT_Pos val, const FontAtlas& atlas)
|
||||||
void TextView::typesetGlyphs(const std::string& str, const zeus::CColor& defaultColor)
|
void TextView::typesetGlyphs(const std::string& str, const zeus::CColor& defaultColor)
|
||||||
{
|
{
|
||||||
UTF8Iterator it(str.begin());
|
UTF8Iterator it(str.begin());
|
||||||
size_t charLen = str.size() ? std::min(it.countTo(str.end()), size_t(1024)) : 0;
|
size_t charLen = str.size() ? std::min(it.countTo(str.end()), m_capacity) : 0;
|
||||||
_commitResources(charLen);
|
_commitResources(charLen);
|
||||||
|
|
||||||
uint32_t lCh = -1;
|
uint32_t lCh = -1;
|
||||||
|
@ -477,13 +477,14 @@ void TextView::typesetGlyphs(const std::string& str, const zeus::CColor& default
|
||||||
|
|
||||||
void TextView::typesetGlyphs(const std::wstring& str, const zeus::CColor& defaultColor)
|
void TextView::typesetGlyphs(const std::wstring& str, const zeus::CColor& defaultColor)
|
||||||
{
|
{
|
||||||
_commitResources(str.size());
|
size_t charLen = std::min(str.size(), m_capacity);
|
||||||
|
_commitResources(charLen);
|
||||||
|
|
||||||
uint32_t lCh = -1;
|
uint32_t lCh = -1;
|
||||||
m_glyphs.clear();
|
m_glyphs.clear();
|
||||||
m_glyphs.reserve(str.size());
|
m_glyphs.reserve(charLen);
|
||||||
m_glyphInfo.clear();
|
m_glyphInfo.clear();
|
||||||
m_glyphInfo.reserve(str.size());
|
m_glyphInfo.reserve(charLen);
|
||||||
int adv = 0;
|
int adv = 0;
|
||||||
|
|
||||||
for (wchar_t ch : str)
|
for (wchar_t ch : str)
|
||||||
|
|
|
@ -387,7 +387,7 @@ void View::commitResources(ViewResources& res, const boo::FactoryCommitFunc& com
|
||||||
|
|
||||||
void View::VertexBufferBindingSolid::init(boo::IGraphicsDataFactory::Context& ctx,
|
void View::VertexBufferBindingSolid::init(boo::IGraphicsDataFactory::Context& ctx,
|
||||||
ViewResources& res, size_t count,
|
ViewResources& res, size_t count,
|
||||||
const UniformBufferPool<ViewBlock>::Token& viewBlockBuf)
|
const hecl::UniformBufferPool<ViewBlock>::Token& viewBlockBuf)
|
||||||
{
|
{
|
||||||
m_vertsBuf.emplace(res.m_viewRes.m_solidPool.allocateBlock(res.m_factory, count));
|
m_vertsBuf.emplace(res.m_viewRes.m_solidPool.allocateBlock(res.m_factory, count));
|
||||||
auto vBufInfo = m_vertsBuf->getBufferInfo();
|
auto vBufInfo = m_vertsBuf->getBufferInfo();
|
||||||
|
@ -422,7 +422,7 @@ void View::VertexBufferBindingSolid::init(boo::IGraphicsDataFactory::Context& ct
|
||||||
|
|
||||||
void View::VertexBufferBindingTex::init(boo::IGraphicsDataFactory::Context& ctx,
|
void View::VertexBufferBindingTex::init(boo::IGraphicsDataFactory::Context& ctx,
|
||||||
ViewResources& res, size_t count,
|
ViewResources& res, size_t count,
|
||||||
const UniformBufferPool<ViewBlock>::Token& viewBlockBuf,
|
const hecl::UniformBufferPool<ViewBlock>::Token& viewBlockBuf,
|
||||||
boo::ITexture* texture)
|
boo::ITexture* texture)
|
||||||
{
|
{
|
||||||
m_vertsBuf.emplace(res.m_viewRes.m_texPool.allocateBlock(res.m_factory, count));
|
m_vertsBuf.emplace(res.m_viewRes.m_texPool.allocateBlock(res.m_factory, count));
|
||||||
|
|
Loading…
Reference in New Issue