Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <chrono>
- struct Members;
- struct Timer
- {
- static void Init();
- static void Reset();
- static float Elapsed();
- static float ElapsedMillis();
- static Timer& get()
- {
- static Timer instance;
- return instance;
- }
- byte m_Reserved[32];
- Members* m_Members;
- };
- typedef std::chrono::high_resolution_clock HighResolutionClock;
- typedef std::chrono::duration<float, std::milli> milliseconds_type;
- struct Members
- {
- std::chrono::time_point<HighResolutionClock> m_Start;
- };
- void Timer::Init()
- {
- get().m_Members = new (get().m_Reserved) Members();
- Reset();
- }
- void Timer::Reset()
- {
- get().m_Members->m_Start = HighResolutionClock::now();
- }
- float Timer::Elapsed()
- {
- return std::chrono::duration_cast<milliseconds_type>(HighResolutionClock::now() - get().m_Members->m_Start).count() / 1000.0f;
- }
- float Timer::ElapsedMillis()
- {
- return Elapsed() * 1000.0f;
- }
- typedef unsigned int uint32;
- namespace mole {
- typedef void (*BackendDispatchFunction)(const void*);
- typedef void* CommandPacket;
- namespace commandPacket {
- static const size_t OFFSET_NEXT_COMMAND_PACKET = 0u;
- static const size_t OFFSET_BACKEND_DISPATCH_FUNCTION = OFFSET_NEXT_COMMAND_PACKET + sizeof(CommandPacket);
- static const size_t OFFSET_COMMAND = OFFSET_BACKEND_DISPATCH_FUNCTION + sizeof(BackendDispatchFunction);
- template <typename T>
- inline CommandPacket Create(size_t auxMemorySize)
- {
- return ::operator new(GetSize<T>(auxMemorySize));
- }
- template <typename T>
- inline size_t GetSize(size_t auxMemorySize)
- {
- return OFFSET_COMMAND + sizeof(T) + auxMemorySize;
- };
- inline CommandPacket* GetNextCommandPacket(CommandPacket packet)
- {
- return reinterpret_cast<CommandPacket*>(reinterpret_cast<char*>(packet) + OFFSET_NEXT_COMMAND_PACKET);
- }
- template <typename T>
- inline CommandPacket* GetNextCommandPacket(T* command)
- {
- return union_cast<CommandPacket*>(reinterpret_cast<char*>(command) - OFFSET_COMMAND + OFFSET_NEXT_COMMAND_PACKET);
- }
- inline BackendDispatchFunction* GetBackendDispatchFunction(CommandPacket packet)
- {
- return reinterpret_cast<BackendDispatchFunction*>(reinterpret_cast<char*>(packet) + OFFSET_BACKEND_DISPATCH_FUNCTION);
- }
- template <typename T>
- inline T* GetCommand(CommandPacket packet)
- {
- return reinterpret_cast<T*>(reinterpret_cast<char*>(packet) + OFFSET_COMMAND);
- }
- template <typename T>
- inline char* GetAuxiliaryMemory(T* command)
- {
- return reinterpret_cast<char*>(command) + sizeof(T);
- }
- inline void StoreNextCommandPacket(CommandPacket packet, CommandPacket nextPacket)
- {
- *commandPacket::GetNextCommandPacket(packet) = nextPacket;
- }
- template <typename T>
- void StoreNextCommandPacket(T* command, CommandPacket nextPacket)
- {
- *commandPacket::GetNextCommandPacket<T>(command) = nextPacket;
- }
- inline void StoreBackendDispatchFunction(CommandPacket packet, BackendDispatchFunction dispatchFunction)
- {
- *commandPacket::GetBackendDispatchFunction(packet) = dispatchFunction;
- }
- inline const CommandPacket LoadNextCommandPacket(const CommandPacket packet)
- {
- return *GetNextCommandPacket(packet);
- }
- inline const BackendDispatchFunction LoadBackendDispatchFunction(const CommandPacket packet)
- {
- return *GetBackendDispatchFunction(packet);
- }
- inline const void* LoadCommand(const CommandPacket packet)
- {
- return reinterpret_cast<char*>(packet) + OFFSET_COMMAND;
- }
- };
- struct CommandBucket
- {
- CommandBucket()
- {
- data = new void* [10 * 1024 * 1024];
- }
- template <typename U>
- U* AddCommand()
- {
- CommandPacket packet = commandPacket::Create<U>(0);
- data[current++] = packet;
- commandPacket::StoreNextCommandPacket(packet, nullptr);
- commandPacket::StoreBackendDispatchFunction(packet, U::DISPATCH_FUNCTION);
- return commandPacket::GetCommand<U>(packet);
- }
- void Submit(void)
- {
- for (unsigned int i = 0; i < current; ++i) {
- CommandPacket packetData = data[i];
- do {
- SubmitPacket(packetData);
- packetData = commandPacket::LoadNextCommandPacket(packetData);
- } while(packetData != nullptr);
- }
- }
- void SubmitPacket(const CommandPacket packet)
- {
- const BackendDispatchFunction function = commandPacket::LoadBackendDispatchFunction(packet);
- const void* command = commandPacket::LoadCommand(packet);
- function(command);
- }
- private:
- void** data;
- uint32 current = 0;
- };
- namespace Commands {
- struct Draw
- {
- static const BackendDispatchFunction DISPATCH_FUNCTION;
- uint32 vertexCount;
- };
- }
- namespace BackendCommands {
- inline void Draw(const void* data)
- {
- }
- }
- const BackendDispatchFunction Commands::Draw::DISPATCH_FUNCTION = &BackendCommands::Draw;
- }
- namespace MyQueue {
- namespace packet {
- struct Base;
- typedef void (*BackendFunction)(const Base* params);
- struct Base
- {
- BackendFunction backendFunction;
- };
- struct BindShader : public Base
- {
- uint32 program;
- static inline void ExecuteBackend(const BindShader* params)
- {
- }
- };
- struct BindVertexArray : public Base
- {
- uint32 vao;
- static inline void ExecuteBackend(const BindVertexArray* params)
- {
- }
- };
- struct Draw : public Base
- {
- uint32 count;
- static inline void ExecuteBackend(const Draw* params)
- {
- }
- };
- union AllPackets
- {
- public:
- BackendFunction execute;
- private:
- Base Base;
- BindShader BindProgram;
- BindVertexArray BindVertexArray;
- Draw DrawArrays;
- };
- }
- struct CommandBucket
- {
- CommandBucket()
- : maxPackets(0),
- packets(nullptr)
- {
- packetCount = 0;
- }
- ~CommandBucket()
- {
- delete[] packets;
- packets = nullptr;
- maxPackets = 0;
- }
- void Init()
- {
- maxPackets = 10 * 1024 * 1024;
- packetCount = 0;
- packets = new packet::AllPackets[maxPackets];
- memset(packets, 0, maxPackets * sizeof(packet::AllPackets));
- }
- void Clear()
- {
- packetCount = 0;
- }
- void Submit()
- {
- const packet::AllPackets* pPacket;
- if(!packetCount)
- return;
- for(pPacket = packets; pPacket->execute != nullptr; pPacket++) {
- pPacket->execute((packet::Base*)pPacket);
- }
- }
- inline void BindProgram(uint32 program)
- {
- packet::BindShader* pPacket = NextPacket<packet::BindShader>();
- pPacket->backendFunction = packet::BackendFunction(packet::BindShader::ExecuteBackend);
- pPacket->program = program;
- }
- inline void BindVertexArray(uint32 vao)
- {
- packet::BindVertexArray* pPacket = NextPacket<packet::BindVertexArray>();
- pPacket->backendFunction = packet::BackendFunction(packet::BindVertexArray::ExecuteBackend);
- pPacket->vao = vao;
- }
- inline void DrawArrays(uint32 count)
- {
- packet::Draw* pPacket = NextPacket<packet::Draw>();
- pPacket->backendFunction = packet::BackendFunction(packet::Draw::ExecuteBackend);
- pPacket->count = count;
- }
- private:
- unsigned int maxPackets;
- packet::AllPackets* packets;
- unsigned int packetCount;
- template <typename T>
- T* NextPacket() { return reinterpret_cast<T*>(&packets[packetCount++]); }
- };
- }
- int main()
- {
- Timer::Init();
- MyQueue::CommandBucket myQueue;
- myQueue.Init(10 * 1024 * 1024);
- Timer::Reset();
- for(int i = 0; i < 40000; ++i) {
- myQueue.DrawArrays(5);
- }
- std::cout << "myQueue: adding 40k draw commands took " << Timer::ElapsedMillis() << "ms\n";
- Timer::Reset();
- myQueue.Submit();
- std::cout << "myQueue: submitting 40k draw commands took " << Timer::ElapsedMillis() << "ms\n";
- mole::CommandBucket molecularQueue;
- Timer::Reset();
- for(int i = 0; i < 40000; ++i) {
- mole::Commands::Draw* draw = molecularQueue.AddCommand<mole::Commands::Draw>();
- draw->vertexCount = 5;
- }
- std::cout << "molecularQueue: adding 40k draw commands took " << Timer::ElapsedMillis() << "ms\n";
- Timer::Reset();
- molecularQueue.Submit();
- std::cout << "molecularQueue: submitting 40k draw commands took " << Timer::ElapsedMillis() << "ms\n";
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement