Subversion Repository Public Repository

Divide-Framework

This repository has no backups
This repository's network speed is throttled to 100KB/sec

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#include "Headers/RenderBin.h"

#include "Core/Headers/Console.h"
#include "Utility/Headers/Localization.h"
#include "Graphs/Headers/SceneGraphNode.h"
#include "Geometry/Shapes/Headers/Object3D.h"
#include "Geometry/Material/Headers/Material.h"
#include "Platform/Video/Headers/GFXDevice.h"

namespace Divide {

RenderBinItem::RenderBinItem(RenderStage currentStage, 
                             I32 sortKeyA,
                             I32 sortKeyB,
                             F32 distToCamSq,
                             RenderingComponent& renderable)
    : _renderable(&renderable),
      _sortKeyA(sortKeyA),
      _sortKeyB(sortKeyB),
      _distanceToCameraSq(distToCamSq)
{
    _stateHash = 0;
    const Material_ptr& nodeMaterial = _renderable->getMaterialInstance();
    // If we do not have a material, no need to continue
    if (!nodeMaterial) {
        return;
    }
    // Sort by state hash depending on the current rendering stage
    // Save the render state hash value for sorting
    _stateHash = renderable.getDrawStateHash(currentStage);
}

/// Sorting opaque items is a 3 step process:
/// 1: sort by shaders
/// 2: if the shader is identical, sort by state hash
/// 3: if shader is identical and state hash is identical, sort by albedo ID
struct RenderQueueKeyCompare {
    // Sort
    bool operator()(const RenderBinItem& a, const RenderBinItem& b) const {
        // Sort by shader in all states The sort key is the shader id (for now)
        if (a._sortKeyA != b._sortKeyA) {
            return a._sortKeyA < b._sortKeyA;
        }
        // If the shader values are the same, we use the state hash for sorting
        // The _stateHash is a CRC value created based on the RenderState.
        if (a._stateHash != b._stateHash) {
            return a._stateHash < b._stateHash;
        }
        // If both the shader are the same and the state hashes match,
        // we sort by the secondary key (usually the texture id)
        return a._sortKeyB < b._sortKeyB;
    }
};

struct RenderQueueDistanceBackToFront {
    bool operator()(const RenderBinItem& a, const RenderBinItem& b) const {
       return a._distanceToCameraSq > b._distanceToCameraSq;
    }
};

struct RenderQueueDistanceFrontToBack {
    bool operator()(const RenderBinItem& a, const RenderBinItem& b) const {
        return a._distanceToCameraSq < b._distanceToCameraSq;
    }
};

RenderBin::RenderBin(RenderBinType rbType,
                     RenderingOrder::List renderOrder)
    : _binIndex(0),
      _rbType(rbType),
      _binPropertyMask(0),
      _renderOrder(renderOrder)
{
    _renderBinStack.reserve(125);

    if(_rbType != +RenderBinType::RBT_OPAQUE &&  _rbType != +RenderBinType::RBT_TERRAIN)  {
        SetBit(_binPropertyMask, to_const_uint(RenderBitProperty::TRANSLUCENT));
    } else {
        ClearBit(_binPropertyMask, to_const_uint(RenderBitProperty::TRANSLUCENT));
    }
}

RenderBin::~RenderBin()
{
}

void RenderBin::sort(const std::atomic_bool& stopRequested, RenderStage renderStage) {
    // WriteLock w_lock(_renderBinGetMutex);
    switch (_renderOrder) {
        default:
        case RenderingOrder::List::BY_STATE: {
            if (GFX_DEVICE.isDepthStage()) {
                std::sort(std::begin(_renderBinStack),
                          std::end(_renderBinStack),
                          RenderQueueDistanceFrontToBack());
            } else {
                std::sort(std::begin(_renderBinStack),
                          std::end(_renderBinStack),
                          RenderQueueKeyCompare());
            }
        } break;
        case RenderingOrder::List::BACK_TO_FRONT: {
            std::sort(std::begin(_renderBinStack),
                      std::end(_renderBinStack),
                      RenderQueueDistanceBackToFront());
        } break;
        case RenderingOrder::List::FRONT_TO_BACK: {
            std::sort(std::begin(_renderBinStack),
                      std::end(_renderBinStack),
                      RenderQueueDistanceFrontToBack());
        } break;
        case RenderingOrder::List::NONE: {
            // no need to sort
        } break;
        case RenderingOrder::List::COUNT: {
            Console::errorfn(Locale::get(_ID("ERROR_INVALID_RENDER_BIN_SORT_ORDER")),
                             _rbType._to_string());
        } break;
    };

    U32 index = _binIndex;
    for (RenderBinItem& item : _renderBinStack) {
        Attorney::RenderingCompRenderBin::drawOrder(*item._renderable, index++);
    }
}

void RenderBin::refresh() {
    // WriteLock w_lock(_renderBinGetMutex);
    _renderBinStack.resize(0);
    _renderBinStack.reserve(128);
}

void RenderBin::addNodeToBin(const SceneGraphNode& sgn, RenderStage stage, const vec3<F32>& eyePos) {
    I32 keyA = to_uint(_renderBinStack.size() + 1);
    I32 keyB = keyA;

    RenderingComponent* const renderable = sgn.get<RenderingComponent>();

    const Material_ptr& nodeMaterial = renderable->getMaterialInstance();
    if (nodeMaterial) {
        nodeMaterial->getSortKeys(keyA, keyB);
    }

    vectorAlg::emplace_back(_renderBinStack, 
                            stage,
                            keyA,
                            keyB,
                            sgn.get<BoundsComponent>()->getBoundingBox().nearestDistanceFromPointSquared(eyePos),
                            *renderable);
}

void RenderBin::populateRenderQueue(const std::atomic_bool& stopRequested, RenderStage renderStage) {
    GFXDevice& gfx = GFX_DEVICE;
    I32 renderQueueIndex = gfx.reserveRenderQueue();
    // We need to apply different materials for each stage. As nodes are sorted, this should be very fast
    for (const RenderBinItem& item : _renderBinStack) {
        if (stopRequested) {
            break;
        }
        gfx.addToRenderQueue(renderQueueIndex,
                             Attorney::RenderingCompRenderBin::getRenderData(*item._renderable, renderStage));
    }
}

void RenderBin::postRender(const SceneRenderState& renderState, RenderStage renderStage, RenderSubPassCmds& subPassesInOut) {
    for (const RenderBinItem& item : _renderBinStack) {
        Attorney::RenderingCompRenderBin::postRender(*item._renderable, renderState, renderStage, subPassesInOut);
    }
}
};

Commits for Divide-Framework/trunk/Source Code/Rendering/RenderPass/RenderBin.cpp

Diff revisions: vs.
Revision Author Commited Message
781 Diff Diff IonutCava picture IonutCava Wed 12 Oct, 2016 16:03:46 +0000

[IonutCava]
- ShaderComputeQueue <-> Material shader request bug fix (element stuck in QUEUED state)
- More Camera class cleanups
- Add a method of removing EnvironmentProbes from their Pool

777 Diff Diff IonutCava picture IonutCava Fri 07 Oct, 2016 16:14:48 +0000

[IonutCava]
- Continue to implement CommandBuffer / RenderPass / RenderSubPass system.
— Rendering artefacts are still present.

709 Diff Diff IonutCava picture IonutCava Thu 19 May, 2016 16:21:46 +0000

[IonutCava]
- Massive rewrite of the resource system:
— ResourceCache now uses a map of weak pointers and passes shared pointers to the call point of CreateResource
— RemoveResource is no longer needed, but resource based smart pointers use a custom deleter that calls unload()
— Keep a shared_ptr of the resource in the entity that needs it and pass shared_ptr references from getter methods
-— All of this removed the need for calls to RemoveResource, REGISTER_TRACKED_DEPENDENCY and UNREGISTER_TRACKED_DEPENDENCY reducing the number of mutex locks and atomic exchanges
- Singleton cleanup:
— Removed ShaderManager singleton and merged it’s data and responsibilities in static methods in both ShaderProgram and Shader classes.
Explanation: Due to the complex interdependency chains in the system, copying, updating, tracking the cache in a thread safe way became a lot more slower than a straight forward smart pointer based implementation. (e.g. scene graph nodes have 3d objects and material instances, 3d objects have materials, materials have textures and shaders, etc)

706 Diff Diff IonutCava picture IonutCava Fri 13 May, 2016 16:29:40 +0000

[IonutCava]
- Renamed LightManager to LightPool and changed it from a Singleton to a scene specific pointer
- More scene load / unload updates (changing scenes now works properly!)
- Allowed GUI interface to hold per-scene elements and only render relevant ones
- Reduced dependencies between nodes, scenemanager, scene, loaders and kernel
- Removed Reflector base class as it was useless and integrate Water class with the Reflection system already in place
- Extended RenderingComponent’s reflection system to allow refraction as well

664 Diff Diff IonutCava picture IonutCava Wed 30 Mar, 2016 16:23:51 +0000

[IonutCava]
- Split some render bin loops into multiple tasks
- Cleaned up the Task class
- Attempt to improve Console multithreaded performance (does not compile yet)

662 Diff Diff IonutCava picture IonutCava Mon 28 Mar, 2016 18:46:06 +0000

[Ionut]
- stopRequested param for Task callbacks should be an atomic const reference
- DebugInterface thread safety updates
- Initial code for locked Tasks (tasks that can’t be reset)

660 Diff Diff IonutCava picture IonutCava Mon 21 Mar, 2016 17:11:19 +0000

[IonutCava]
- Finish Parent<->Children thread pool system
- Use new thread pool system for most multithreaded tasks in the engine: culling, sorting, light preparation, etc
- Add platform specific init/close calls at the start and end of the main function for future use

649 Diff Diff IonutCava picture IonutCava Mon 22 Feb, 2016 17:16:17 +0000

[IonutCava]
- Attempt to uncouple PhysicsComponent from BoundsComponent

648 Diff Diff IonutCava picture IonutCava Sun 21 Feb, 2016 16:32:52 +0000

[IonutCava]
- Update copyright notice
- Move BoundingBox and BoundingSphere to a new BoundsComponent
— Add a temp hack in SceneGraphNode to update these

643 IonutCava picture IonutCava Sat 13 Feb, 2016 12:36:20 +0000

[IonutCava]
- Add support for multiple GFX render queues
— Flush all queues in a tight loop
— This may allow populating the render queues from renderbins in parallel