Skip to content

Commit

Permalink
- A few changes to resource loading to increase throughput a bit.
Browse files Browse the repository at this point in the history
- A few changes to the material system to reduce the number of shader permutations a bit
  • Loading branch information
IonutCava committed Mar 24, 2019
1 parent db4422c commit c1a4823
Show file tree
Hide file tree
Showing 15 changed files with 109 additions and 116 deletions.
26 changes: 15 additions & 11 deletions Source Code/Core/Resources/Headers/ResourceCache.h
Expand Up @@ -34,8 +34,8 @@
#define RESOURCE_MANAGER_H_

#include "ResourceLoader.h"
#include "Platform/Threading/Headers/ThreadPool.h"

#include "Core/Headers/Console.h"
#include "Utility/Headers/Localization.h"
#include "Core/Headers/PlatformContextComponent.h"

Expand Down Expand Up @@ -94,21 +94,25 @@ class ResourceCache : public PlatformContextComponent {
ResourceLoadLock res_lock(loadingHash);

/// Check cache first to avoid loading the same resource twice
std::shared_ptr<T> ptr = std::static_pointer_cast<T>(loadResource(loadingHash, descriptor.resourceName()));
std::shared_ptr<T> ptr = std::static_pointer_cast<T>(find(loadingHash));
/// If the cache did not contain our resource ...
wasInCache = ptr != nullptr;
if (!ptr) {
if (!wasInCache) {
Console::printfn(Locale::get(_ID("RESOURCE_CACHE_GET_RES")), descriptor.resourceName().c_str(), loadingHash);

/// ...aquire the resource's loader
/// and get our resource as the loader creates it
ptr = std::static_pointer_cast<T>(ImplResourceLoader<T>(*this, _context, descriptor, loadingHash)());
if (ptr) {
/// validate it's integrity and add it to the cache
add(ptr);
}
} else {
if (descriptor.onLoadCallback()) {
descriptor.onLoadCallback()(ptr);
}
assert(ptr != nullptr);
add(ptr);
}

if (descriptor.waitForReady()) {
WAIT_FOR_CONDITION(ptr->getState() == ResourceState::RES_LOADED);
}

if (wasInCache && descriptor.onLoadCallback()) {
descriptor.onLoadCallback()(ptr);
}

return ptr;
Expand Down
3 changes: 3 additions & 0 deletions Source Code/Core/Resources/Headers/ResourceDescriptor.h
Expand Up @@ -105,6 +105,7 @@ class ResourceDescriptor : public Hashable {
inline U32 getID() const { return _ID; }
inline P32 getMask() const { return _mask; }
inline const vec3<U16>& getData() const { return _data; }
inline bool waitForReady() const { return _waitForReady; }

const DELEGATE_CBK<void, CachedResource_wptr>& onLoadCallback() const {
return _onLoadCallback;
Expand All @@ -123,6 +124,7 @@ class ResourceDescriptor : public Hashable {
inline void setID(U32 ID) { _ID = ID; }
inline void setBoolMask(P32 mask) { _mask = mask; }
inline void setData(const vec3<U16>& data) { _data.set(data); }
inline void waitForReady(bool state) { _waitForReady = state; }

inline void setThreadedLoading(const bool threaded) {
_threaded = threaded;
Expand All @@ -149,6 +151,7 @@ class ResourceDescriptor : public Hashable {
stringImpl _assetLocation;
bool _flag = false;
bool _threaded = true;
bool _waitForReady = true;
U32 _ID = 0;
/// 4 bool values representing ... anything ...
P32 _mask;
Expand Down
15 changes: 1 addition & 14 deletions Source Code/Core/Resources/ResourceCache.cpp
Expand Up @@ -2,8 +2,6 @@

#include "Headers/ResourceCache.h"

#include "Core/Headers/Console.h"
#include "Utility/Headers/Localization.h"
#include "Environment/Terrain/Headers/TerrainLoader.h"
#include "Core/Time/Headers/ApplicationTimer.h"

Expand Down Expand Up @@ -78,17 +76,6 @@ void ResourceCache::add(CachedResource_wptr res) {
hashAlg::insert(_resDB, hashAlg::make_pair(hash, res));
}

CachedResource_ptr ResourceCache::loadResource(size_t descriptorHash, const stringImpl& resourceName) {
const CachedResource_ptr& resource = find(descriptorHash);
if (resource) {
WAIT_FOR_CONDITION(resource->getState() == ResourceState::RES_LOADED);
} else {
Console::printfn(Locale::get(_ID("RESOURCE_CACHE_GET_RES")), resourceName.c_str(), descriptorHash);
}

return resource;
}

CachedResource_ptr ResourceCache::find(size_t descriptorHash) {
/// Search in our resource cache
SharedLock r_lock(_creationMutex);
Expand All @@ -97,7 +84,7 @@ CachedResource_ptr ResourceCache::find(size_t descriptorHash) {
return it->second.lock();
}

return {};
return nullptr;
}

void ResourceCache::remove(CachedResource* resource) {
Expand Down
1 change: 1 addition & 0 deletions Source Code/Core/Resources/ResourceDescriptor.cpp
Expand Up @@ -16,6 +16,7 @@ ResourceDescriptor::ResourceDescriptor(const stringImpl& resourceName)
: _propertyDescriptor(nullptr),
_resourceName(resourceName),
_assetName(resourceName),
_waitForReady(true),
_flag(false),
_ID(0),
_enumValue(0),
Expand Down
1 change: 1 addition & 0 deletions Source Code/Environment/Vegetation/Headers/Vegetation.h
Expand Up @@ -149,6 +149,7 @@ class Vegetation : public SceneNode {
static VertexBuffer* s_buffer;
static ShaderBuffer* s_treeData;
static ShaderBuffer* s_grassData;
static vector<Mesh_ptr> s_treeMeshes;
static std::unordered_set<vec2<F32>> s_treePositions;
static std::unordered_set<vec2<F32>> s_grassPositions;

Expand Down
56 changes: 43 additions & 13 deletions Source Code/Environment/Vegetation/Vegetation.cpp
Expand Up @@ -43,6 +43,8 @@ namespace Divide {
namespace {
constexpr U32 WORK_GROUP_SIZE = 64;
constexpr I16 g_maxRadiusSteps = 512;

SharedMutex g_treeMeshLock;
};

bool Vegetation::s_buffersBound = false;
Expand All @@ -52,6 +54,7 @@ std::unordered_set<vec2<F32>> Vegetation::s_grassPositions;
ShaderBuffer* Vegetation::s_treeData = nullptr;
ShaderBuffer* Vegetation::s_grassData = nullptr;
VertexBuffer* Vegetation::s_buffer = nullptr;
vector<Mesh_ptr> Vegetation::s_treeMeshes;
std::atomic_uint Vegetation::s_bufferUsage = 0;
size_t Vegetation::s_maxChunks = 0;
size_t Vegetation::s_maxTreeInstancesPerChunk = 0;
Expand Down Expand Up @@ -86,6 +89,31 @@ Vegetation::Vegetation(GFXDevice& context,

_treeMeshNames.insert(eastl::cend(_treeMeshNames), eastl::cbegin(details.treeMeshes), eastl::cend(details.treeMeshes));

{
UniqueLockShared w_lock(g_treeMeshLock);
for (const stringImpl& meshName : _treeMeshNames) {
if (std::find_if(std::cbegin(s_treeMeshes), std::cend(s_treeMeshes),
[&meshName](const Mesh_ptr& ptr) {
return Util::CompareIgnoreCase(ptr->assetName(), meshName);
}) == std::cend(s_treeMeshes))
{
ResourceDescriptor model("Tree");
model.assetLocation(Paths::g_assetsLocation + "models");
model.setFlag(true);
model.setThreadedLoading(false); //< we need the extents asap!
model.assetName(meshName);
Mesh_ptr meshPtr = CreateResource<Mesh>(_context.parent().resourceCache(), model);
meshPtr->setMaterialTpl(s_treeMaterial);
// CSM last split should probably avoid rendering trees since it would cover most of the scene :/
meshPtr->renderState().addToDrawExclusionMask(RenderStagePass(RenderStage::SHADOW, RenderPassType::MAIN_PASS, 0, 2));
for (const SubMesh_ptr& subMesh : meshPtr->subMeshList()) {
subMesh->renderState().addToDrawExclusionMask(RenderStagePass(RenderStage::SHADOW, RenderPassType::MAIN_PASS, 0, 2));
}
s_treeMeshes.push_back(meshPtr);
}
}
}

ResourceDescriptor instanceCullShaderGrass("instanceCullVegetation.Grass");
instanceCullShaderGrass.setThreadedLoading(true);
assert(s_maxGrassInstancesPerChunk != 0u && "Vegetation error: call \"precomputeStaticData\" first!");
Expand Down Expand Up @@ -149,6 +177,8 @@ Vegetation::~Vegetation()
}
assert(getState() != ResourceState::RES_LOADING);
if (s_bufferUsage.fetch_sub(1) == 1) {
UniqueLockShared w_lock(g_treeMeshLock);
s_treeMeshes.clear();
s_treeMaterial.reset();
}

Expand Down Expand Up @@ -393,25 +423,25 @@ void Vegetation::postLoad(SceneGraphNode& sgn) {

U32 ID = _terrainChunk.ID();
U32 meshID = to_U32(ID % _treeMeshNames.size());

ResourceDescriptor model("Tree");
model.assetLocation(Paths::g_assetsLocation + "models");
model.setFlag(true);
model.setThreadedLoading(false); //< we need the extents asap!
model.assetName(_treeMeshNames[meshID]);
Mesh_ptr meshPtr = CreateResource<Mesh>(_context.parent().resourceCache(), model);
meshPtr->setMaterialTpl(s_treeMaterial);
// CSM last split should probably avoid rendering trees since it would cover most of the scene :/
meshPtr->renderState().addToDrawExclusionMask(RenderStagePass(RenderStage::SHADOW, RenderPassType::MAIN_PASS, 0, 2));
for (const SubMesh_ptr& subMesh : meshPtr->subMeshList()) {
subMesh->renderState().addToDrawExclusionMask(RenderStagePass(RenderStage::SHADOW, RenderPassType::MAIN_PASS, 0, 2));
const stringImpl& meshName = _treeMeshNames[meshID];

Mesh_ptr crtMesh = nullptr;
{
SharedLock r_lock(g_treeMeshLock);
crtMesh = s_treeMeshes.front();
for (const Mesh_ptr& mesh : s_treeMeshes) {
if (Util::CompareIgnoreCase(mesh->assetName(), meshName)) {
crtMesh = mesh;
break;
}
}
}

SceneGraphNodeDescriptor nodeDescriptor = {};
nodeDescriptor._componentMask = normalMask;
nodeDescriptor._usageContext = NodeUsageContext::NODE_STATIC;
nodeDescriptor._serialize = false;
nodeDescriptor._node = meshPtr;
nodeDescriptor._node = crtMesh;
nodeDescriptor._instanceCount = _instanceCountTrees;

assert(s_grassData != nullptr);
Expand Down
10 changes: 3 additions & 7 deletions Source Code/Geometry/Material/Headers/ShaderComputeQueue.h
Expand Up @@ -35,7 +35,6 @@ OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "ShaderProgramInfo.h"
#include "Core/Resources/Headers/ResourceCache.h"
#include "Managers/Headers/FrameListenerManager.h"

namespace Divide {

Expand All @@ -46,7 +45,7 @@ namespace Time {
class ResourceCache;
class PlatformContext;

class ShaderComputeQueue : public FrameListener {
class ShaderComputeQueue {
public:
class ShaderQueueElement {
public:
Expand Down Expand Up @@ -77,9 +76,8 @@ class ShaderComputeQueue : public FrameListener {
// Return true if the queue wasn't empty
bool stepQueue();

protected:
bool frameStarted(const FrameEvent& evt) override;
bool frameEnded(const FrameEvent& evt) override;
private:
bool stepQueueLocked();

private:
ResourceCache& _cache;
Expand All @@ -88,8 +86,6 @@ class ShaderComputeQueue : public FrameListener {

std::mutex _queueLock;
std::deque<ShaderQueueElement> _shaderComputeQueue;
bool _shadersComputedThisFrame = false;
U32 _totalShaderComputeCountThisFrame = 0;
U32 _totalShaderComputeCount = 0;
};

Expand Down
39 changes: 11 additions & 28 deletions Source Code/Geometry/Material/Material.cpp
Expand Up @@ -495,15 +495,6 @@ bool Material::computeShader(RenderStagePass renderStagePass) {

shaderPropertyDescriptor._defines.insert(std::cbegin(shaderPropertyDescriptor._defines), std::cbegin(_extraShaderDefines), std::cend(_extraShaderDefines));

if (renderStagePass._stage == RenderStage::SHADOW) {
shaderPropertyDescriptor._defines.push_back(std::make_pair("SHADOW_PASS", true));
}

if (renderStagePass._passType == RenderPassType::PRE_PASS) {
shaderPropertyDescriptor._defines.push_back(std::make_pair("PRE_PASS", true));
} else if (renderStagePass._passType == RenderPassType::OIT_PASS) {
shaderPropertyDescriptor._defines.push_back(std::make_pair("OIT_PASS", true));
}

if (_textures[slot1]) {
if (!_textures[slot0]) {
Expand All @@ -515,11 +506,18 @@ bool Material::computeShader(RenderStagePass renderStagePass) {
stringImpl shader = _baseShaderName[renderStagePass.isDepthPass() ? 1 : 0];

if (renderStagePass.isDepthPass()) {
shader += renderStagePass._stage == RenderStage::SHADOW ? ".Shadow" : ".PrePass";
if (renderStagePass._stage == RenderStage::SHADOW) {
shader += ".Shadow";
shaderPropertyDescriptor._defines.push_back(std::make_pair("SHADOW_PASS", true));
} else {
shader += ".PrePass";
shaderPropertyDescriptor._defines.push_back(std::make_pair("PRE_PASS", true));
}
}

if (renderStagePass._passType == RenderPassType::OIT_PASS) {
shader += ".OIT";
shaderPropertyDescriptor._defines.push_back(std::make_pair("OIT_PASS", true));
}

if (!renderStagePass.isDepthPass()) {
Expand Down Expand Up @@ -572,43 +570,28 @@ bool Material::computeShader(RenderStagePass renderStagePass) {
shaderPropertyDescriptor._defines.push_back(std::make_pair("USE_DOUBLE_SIDED", true));
}

if (isRefractive()) {
shader += ".Refractive";
shaderPropertyDescriptor._defines.push_back(std::make_pair("IS_REFRACTIVE", true));
}

if (isReflective()) {
shader += ".Reflective";
shaderPropertyDescriptor._defines.push_back(std::make_pair("IS_REFLECTIVE", true));
}

if (!receivesShadows() || !_context.context().config().rendering.shadowMapping.enabled) {
shader += ".NoShadows";
shaderPropertyDescriptor._defines.push_back(std::make_pair("DISABLE_SHADOW_MAPPING", true));
}


// Add the GPU skinning module to the vertex shader?
if (_hardwareSkinning) {
shaderPropertyDescriptor._defines.push_back(std::make_pair("USE_GPU_SKINNING", true));
shader += ",Skinned"; //<Use "," instead of "." will add a Vertex only property
}

if (_useTriangleStrip) {
shader += ".TriangleSrip";
shaderPropertyDescriptor._defines.push_back(std::make_pair("USE_TRIANGLE_STRIP", true));
}

switch (_shadingMode) {
default:
case ShadingMode::FLAT: {
shaderPropertyDescriptor._defines.push_back(std::make_pair("USE_SHADING_FLAT", true));
shader += ".Flat";
} break;
case ShadingMode::PHONG: {
/*case ShadingMode::PHONG: {
shaderPropertyDescriptor._defines.push_back(std::make_pair("USE_SHADING_PHONG", true));
shader += ".Phong";
} break;
} break;*/
case ShadingMode::PHONG:
case ShadingMode::BLINN_PHONG: {
shaderPropertyDescriptor._defines.push_back(std::make_pair("USE_SHADING_BLINN_PHONG", true));
shader += ".BlinnPhong";
Expand Down

0 comments on commit c1a4823

Please sign in to comment.