Skip to content

Commit

Permalink
Updated vertex cache to use ls::utils cache types. Enabled vertex cac…
Browse files Browse the repository at this point in the history
…hing due to performance improvements.
  • Loading branch information
hamsham committed Jan 29, 2022
1 parent 23d540b commit 682eb85
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 229 deletions.
2 changes: 1 addition & 1 deletion softlight/include/softlight/SL_Config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* Vertex Processing Configuration
-----------------------------------------------------------------------------*/
#ifndef SL_VERTEX_CACHING_ENABLED
#define SL_VERTEX_CACHING_ENABLED 0
#define SL_VERTEX_CACHING_ENABLED 1
#endif /* SL_VERTEX_CACHING_ENABLED */

#ifndef SL_VERTEX_CACHE_SIZE
Expand Down
101 changes: 15 additions & 86 deletions softlight/include/softlight/SL_VertexCache.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,109 +2,38 @@
#ifndef SL_VERTEX_CACHE_HPP
#define SL_VERTEX_CACHE_HPP

#include "lightsky/utils/IndexedCache.hpp"
#include "lightsky/utils/LRUCache.hpp"
#include "lightsky/utils/LRU8WayCache.hpp"

#include "lightsky/math/mat4.h"

#include "softlight/SL_Config.hpp"
#include "softlight/SL_Shader.hpp" // SL_VertexParam
#include "softlight/SL_ShaderUtil.hpp" // SL_VERTEX_CACHE_SIZE



static_assert(ls::math::is_pow2<size_t>(SL_VERTEX_CACHE_SIZE), "Vertex cache size must be a power of 2.");



/**
* @brief Pre-Transform Vertex Cache
*
* This class helps to cache vertices immediately output from a shader.
*/
class SL_PTVCache
{
private:
enum : size_t
{
PTV_CACHE_SIZE = SL_VERTEX_CACHE_SIZE,
PTV_CACHE_MISS = ~(size_t)0,
};

static_assert(ls::math::is_pow2<size_t>(PTV_CACHE_SIZE), "Vertex cache size must be a power of 2.");

size_t mIndices[PTV_CACHE_SIZE];

SL_VertexParam* mParam;

ls::math::vec4_t<float> (*mShader)(SL_VertexParam&);

SL_TransformedVert mVertices[PTV_CACHE_SIZE];

public:
SL_PTVCache(ls::math::vec4_t<float> (*pShader)(SL_VertexParam&), SL_VertexParam& inParam) noexcept;

SL_PTVCache(const SL_PTVCache&) noexcept;

SL_PTVCache(SL_PTVCache&&) noexcept;

SL_PTVCache& operator=(const SL_PTVCache&) noexcept;

SL_PTVCache& operator=(SL_PTVCache&&) noexcept;

bool have_key(size_t key) const noexcept;

SL_TransformedVert* query_and_update(size_t key, const ls::math::mat4& scissorMat) noexcept;

void query_and_update(size_t key, const ls::math::mat4& scissorMat, SL_TransformedVert& out) noexcept;

void reset(ls::math::vec4_t<float> (*pShader)(SL_VertexParam&), SL_VertexParam& inParam) noexcept;
};
typedef ls::utils::IndexedCache<SL_TransformedVert, SL_VERTEX_CACHE_SIZE> SL_PTVCache;
//typedef ls::utils::LRUCache<SL_TransformedVert, SL_VERTEX_CACHE_SIZE> SL_PTVCache;
//typedef ls::utils::LRU8WayCache<SL_TransformedVert> SL_PTVCache;



/*-------------------------------------
* Constructor
-------------------------------------*/
inline LS_INLINE SL_PTVCache::SL_PTVCache(ls::math::vec4_t<float> (*pShader)(SL_VertexParam&), SL_VertexParam& inParam) noexcept
{
reset(pShader, inParam);
}



/*-------------------------------------
* Determine if an element is in the cache
-------------------------------------*/
inline LS_INLINE bool SL_PTVCache::have_key(size_t key) const noexcept
{
const size_t i = key & (PTV_CACHE_SIZE-1);
return mIndices[i] == key;
}



/*-------------------------------------
* Query the cache or insert a new element
-------------------------------------*/
inline LS_INLINE SL_TransformedVert* SL_PTVCache::query_and_update(size_t key, const ls::math::mat4& scissorMat) noexcept
{
const size_t i = key & (PTV_CACHE_SIZE-1);

if (LS_UNLIKELY(mIndices[i] != key))
{
mIndices[i] = key;
mParam->vertId = key;
mParam->pVaryings = mVertices[i].varyings;
mVertices[i].vert = scissorMat * mShader(*mParam);
}

return mVertices+i;
}



/*-------------------------------------
* Query the cache or insert a new element
-------------------------------------*/
inline LS_INLINE void SL_PTVCache::query_and_update(size_t key, const ls::math::mat4& scissorMat, SL_TransformedVert& out) noexcept
template <typename UpdateFunc>
inline LS_INLINE void sl_cache_query_or_update(SL_PTVCache& cache, size_t key, SL_TransformedVert& out, const UpdateFunc& func) noexcept
{
static_assert(SL_SHADER_MAX_VARYING_VECTORS == 4, "Please update the vertex varying count.");

const SL_TransformedVert* pIn = query_and_update(key, scissorMat);
const SL_TransformedVert& cacheVal = cache.query_or_update(key, func);
const SL_TransformedVert* pIn = &cacheVal;

#if defined(LS_X86_SSE)
out.vert.simd = _mm_load_ps(reinterpret_cast<const float*>(pIn)+0);
Expand Down
11 changes: 8 additions & 3 deletions softlight/src/SL_LineProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,12 @@ void SL_LineProcessor::process_verts(
begin += m.elementBegin;
end += m.elementBegin;

SL_PTVCache ptvCache{vertShader, params};
SL_PTVCache ptvCache{};
const auto&& vertTransform = [&](size_t key, SL_TransformedVert& tv)->void {
params.vertId = key;
params.pVaryings = tv.varyings;
tv.vert = scissorMat * vertShader(params);
};

#else
const size_t begin = m.elementBegin + mThreadId * 2u;
Expand All @@ -298,8 +303,8 @@ void SL_LineProcessor::process_verts(
const size_t vertId0 = usingIndices ? pIbo->index(index0) : index0;
const size_t vertId1 = usingIndices ? pIbo->index(index1) : index1;

ptvCache.query_and_update(vertId0, scissorMat, pVert0);
ptvCache.query_and_update(vertId1, scissorMat, pVert1);
sl_cache_query_or_update(ptvCache, vertId0, pVert0, vertTransform);
sl_cache_query_or_update(ptvCache, vertId1, pVert1, vertTransform);

#else
params.vertId = usingIndices ? pIbo->index(index0) : index0;
Expand Down
9 changes: 7 additions & 2 deletions softlight/src/SL_PointProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,12 +226,17 @@ void SL_PointProcessor::process_verts(
begin += m.elementBegin;
end += m.elementBegin;

SL_PTVCache ptvCache{vertShader, params};
SL_PTVCache ptvCache{};
const auto&& vertTransform = [&](size_t key, SL_TransformedVert& tv)->void {
params.vertId = key;
params.pVaryings = tv.varyings;
tv.vert = scissorMat * vertShader(params);
};

for (size_t i = begin; i < end; ++i)
{
const size_t vertId = usingIndices ? pIbo->index(i) : i;
ptvCache.query_and_update(vertId, scissorMat, pVert0);
sl_cache_query_or_update(ptvCache, vertId, pVert0, vertTransform);

if (pVert0.vert[3] > 0.f)
{
Expand Down
14 changes: 10 additions & 4 deletions softlight/src/SL_TriProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -798,7 +798,13 @@ void SL_TriProcessor::process_verts(
begin += m.elementBegin;
end += m.elementBegin;

SL_PTVCache ptvCache{vertShader, params};
SL_PTVCache ptvCache{};
const auto&& vertTransform = [&](size_t key, SL_TransformedVert& tv)->void {
params.vertId = key;
params.pVaryings = tv.varyings;
tv.vert = scissorMat * vertShader(params);
};

#else
//const size_t begin = m.elementBegin + mThreadId * 3u;
const size_t begin = m.elementBegin + ((instanceId + mThreadId) % mNumThreads) * 3u;
Expand All @@ -811,9 +817,9 @@ void SL_TriProcessor::process_verts(
const math::vec4_t<size_t>&& vertId = usingIndices ? get_next_vertex3(pIbo, i) : math::vec4_t<size_t>{i+0, i+1, i+2, i+3};

#if SL_VERTEX_CACHING_ENABLED
ptvCache.query_and_update(vertId[0], scissorMat, pVert0);
ptvCache.query_and_update(vertId[1], scissorMat, pVert1);
ptvCache.query_and_update(vertId[2], scissorMat, pVert2);
sl_cache_query_or_update(ptvCache, vertId[0], pVert0, vertTransform);
sl_cache_query_or_update(ptvCache, vertId[1], pVert1, vertTransform);
sl_cache_query_or_update(ptvCache, vertId[2], pVert2, vertTransform);

#else
params.vertId = vertId.v[0];
Expand Down
86 changes: 0 additions & 86 deletions softlight/src/SL_VertexCache.cpp
Original file line number Diff line number Diff line change
@@ -1,88 +1,2 @@

#include "softlight/SL_VertexCache.hpp"



/*-------------------------------------
* Copy Constructor
-------------------------------------*/
SL_PTVCache::SL_PTVCache(const SL_PTVCache& ptv) noexcept :
mParam{ptv.mParam},
mShader{ptv.mShader}
{
for (size_t i = 0; i < PTV_CACHE_SIZE; ++i)
{
mIndices[i] = ptv.mIndices[i];
mVertices[i] = ptv.mVertices[i];
}
}



/*-------------------------------------
* Move Constructor
-------------------------------------*/
SL_PTVCache::SL_PTVCache(SL_PTVCache&& ptv) noexcept :
mParam{ptv.mParam},
mShader{ptv.mShader}
{
for (size_t i = 0; i < PTV_CACHE_SIZE; ++i)
{
mIndices[i] = ptv.mIndices[i];
mVertices[i] = ptv.mVertices[i];
}
}



/*-------------------------------------
* Copy Operator
-------------------------------------*/
SL_PTVCache& SL_PTVCache::operator=(const SL_PTVCache& ptv) noexcept
{
mParam = ptv.mParam;
mShader = ptv.mShader;

for (size_t i = 0; i < PTV_CACHE_SIZE; ++i)
{
mIndices[i] = ptv.mIndices[i];
mVertices[i] = ptv.mVertices[i];
}

return *this;
}



/*-------------------------------------
* Move Operator
-------------------------------------*/
SL_PTVCache& SL_PTVCache::operator=(SL_PTVCache&& ptv) noexcept
{
mParam = ptv.mParam;
mShader = ptv.mShader;

for (size_t i = 0; i < PTV_CACHE_SIZE; ++i)
{
mIndices[i] = ptv.mIndices[i];
mVertices[i] = ptv.mVertices[i];
}

return *this;
}



/*-------------------------------------
* Reset and Re-initialize
-------------------------------------*/
void SL_PTVCache::reset(ls::math::vec4_t<float> (*pShader)(SL_VertexParam&), SL_VertexParam& inParam) noexcept
{
mParam = &inParam;
mShader = pShader;

for (size_t& index : mIndices)
{
index = PTV_CACHE_MISS;
}
}

0 comments on commit 682eb85

Please sign in to comment.