Guest User

Untitled

a guest
Mar 19th, 2020
106
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <iostream>
  2. #include <chrono>
  3.  
  4. struct Members;
  5.  
  6. struct Timer
  7. {
  8.     static void Init();
  9.  
  10.     static void Reset();
  11.  
  12.     static float Elapsed();
  13.     static float ElapsedMillis();
  14.  
  15.     static Timer& get()
  16.     {
  17.         static Timer instance;
  18.         return instance;
  19.     }
  20.  
  21.     byte m_Reserved[32];
  22.     Members* m_Members;
  23. };
  24.  
  25. typedef std::chrono::high_resolution_clock HighResolutionClock;
  26. typedef std::chrono::duration<float, std::milli> milliseconds_type;
  27.  
  28. struct Members
  29. {
  30.     std::chrono::time_point<HighResolutionClock> m_Start;
  31. };
  32.  
  33. void Timer::Init()
  34. {
  35.     get().m_Members = new (get().m_Reserved) Members();
  36.     Reset();
  37. }
  38.  
  39. void Timer::Reset()
  40. {
  41.     get().m_Members->m_Start = HighResolutionClock::now();
  42. }
  43.  
  44. float Timer::Elapsed()
  45. {
  46.     return std::chrono::duration_cast<milliseconds_type>(HighResolutionClock::now() - get().m_Members->m_Start).count() / 1000.0f;
  47. }
  48.  
  49. float Timer::ElapsedMillis()
  50. {
  51.     return Elapsed() * 1000.0f;
  52. }
  53.  
  54. typedef unsigned int uint32;
  55. namespace mole {
  56.     typedef void (*BackendDispatchFunction)(const void*);
  57.     typedef void* CommandPacket;
  58.     namespace commandPacket {
  59.         static const size_t OFFSET_NEXT_COMMAND_PACKET = 0u;
  60.         static const size_t OFFSET_BACKEND_DISPATCH_FUNCTION = OFFSET_NEXT_COMMAND_PACKET + sizeof(CommandPacket);
  61.         static const size_t OFFSET_COMMAND = OFFSET_BACKEND_DISPATCH_FUNCTION + sizeof(BackendDispatchFunction);
  62.  
  63.         template <typename T>
  64.         inline CommandPacket Create(size_t auxMemorySize)
  65.         {      
  66.             return ::operator new(GetSize<T>(auxMemorySize));
  67.         }
  68.  
  69.         template <typename T>
  70.         inline size_t GetSize(size_t auxMemorySize)
  71.         {
  72.             return OFFSET_COMMAND + sizeof(T) + auxMemorySize;
  73.         };
  74.  
  75.         inline CommandPacket* GetNextCommandPacket(CommandPacket packet)
  76.         {
  77.             return reinterpret_cast<CommandPacket*>(reinterpret_cast<char*>(packet) + OFFSET_NEXT_COMMAND_PACKET);
  78.         }
  79.  
  80.         template <typename T>
  81.         inline CommandPacket* GetNextCommandPacket(T* command)
  82.         {
  83.             return union_cast<CommandPacket*>(reinterpret_cast<char*>(command) - OFFSET_COMMAND + OFFSET_NEXT_COMMAND_PACKET);
  84.         }
  85.  
  86.         inline BackendDispatchFunction* GetBackendDispatchFunction(CommandPacket packet)
  87.         {
  88.             return reinterpret_cast<BackendDispatchFunction*>(reinterpret_cast<char*>(packet) + OFFSET_BACKEND_DISPATCH_FUNCTION);
  89.         }
  90.  
  91.         template <typename T>
  92.         inline T* GetCommand(CommandPacket packet)
  93.         {
  94.             return reinterpret_cast<T*>(reinterpret_cast<char*>(packet) + OFFSET_COMMAND);
  95.         }
  96.  
  97.         template <typename T>
  98.         inline char* GetAuxiliaryMemory(T* command)
  99.         {
  100.             return reinterpret_cast<char*>(command) + sizeof(T);
  101.         }
  102.  
  103.         inline void StoreNextCommandPacket(CommandPacket packet, CommandPacket nextPacket)
  104.         {
  105.             *commandPacket::GetNextCommandPacket(packet) = nextPacket;
  106.         }
  107.  
  108.         template <typename T>
  109.         void StoreNextCommandPacket(T* command, CommandPacket nextPacket)
  110.         {
  111.             *commandPacket::GetNextCommandPacket<T>(command) = nextPacket;
  112.         }
  113.  
  114.         inline void StoreBackendDispatchFunction(CommandPacket packet, BackendDispatchFunction dispatchFunction)
  115.         {
  116.             *commandPacket::GetBackendDispatchFunction(packet) = dispatchFunction;
  117.         }
  118.  
  119.         inline const CommandPacket LoadNextCommandPacket(const CommandPacket packet)
  120.         {
  121.             return *GetNextCommandPacket(packet);
  122.         }
  123.  
  124.         inline const BackendDispatchFunction LoadBackendDispatchFunction(const  CommandPacket packet)
  125.         {
  126.             return *GetBackendDispatchFunction(packet);
  127.         }
  128.  
  129.         inline const void* LoadCommand(const CommandPacket packet)
  130.         {
  131.             return reinterpret_cast<char*>(packet) + OFFSET_COMMAND;
  132.         }
  133.     };
  134.  
  135.     struct CommandBucket
  136.     {
  137.         CommandBucket()
  138.         {
  139.             data = new void* [10 * 1024 * 1024];
  140.         }
  141.  
  142.         template <typename U>
  143.         U* AddCommand()
  144.         {
  145.             CommandPacket packet = commandPacket::Create<U>(0);
  146.  
  147.             data[current++] = packet;
  148.  
  149.             commandPacket::StoreNextCommandPacket(packet, nullptr);
  150.             commandPacket::StoreBackendDispatchFunction(packet, U::DISPATCH_FUNCTION);
  151.  
  152.             return commandPacket::GetCommand<U>(packet);
  153.         }
  154.  
  155.         void Submit(void)
  156.         {
  157.             for (unsigned int i = 0; i < current; ++i) {
  158.                 CommandPacket packetData = data[i];
  159.                 do {
  160.                     SubmitPacket(packetData);
  161.                     packetData = commandPacket::LoadNextCommandPacket(packetData);
  162.                 } while(packetData != nullptr);
  163.             }
  164.         }
  165.  
  166.         void SubmitPacket(const CommandPacket packet)
  167.         {
  168.             const BackendDispatchFunction function = commandPacket::LoadBackendDispatchFunction(packet);
  169.             const void* command = commandPacket::LoadCommand(packet);
  170.             function(command);
  171.         }
  172.  
  173.     private:
  174.         void** data;
  175.         uint32 current = 0;
  176.     };
  177.  
  178.     namespace Commands {
  179.         struct Draw
  180.         {
  181.             static const BackendDispatchFunction DISPATCH_FUNCTION;
  182.  
  183.             uint32 vertexCount;
  184.         };
  185.     }
  186.  
  187.     namespace BackendCommands {
  188.         inline void Draw(const void* data)
  189.         {
  190.         }
  191.     }
  192.  
  193.     const BackendDispatchFunction Commands::Draw::DISPATCH_FUNCTION = &BackendCommands::Draw;
  194. }
  195.  
  196. namespace MyQueue {
  197.     namespace packet {
  198.         struct Base;
  199.  
  200.         typedef void (*BackendFunction)(const Base* params);
  201.  
  202.         struct Base
  203.         {
  204.             BackendFunction backendFunction;
  205.         };
  206.  
  207.         struct BindShader : public Base
  208.         {
  209.             uint32 program;
  210.  
  211.             static inline void ExecuteBackend(const BindShader* params)
  212.             {
  213.             }
  214.         };
  215.  
  216.         struct BindVertexArray : public Base
  217.         {
  218.             uint32 vao;
  219.  
  220.             static inline void ExecuteBackend(const BindVertexArray* params)
  221.             {
  222.             }
  223.         };
  224.  
  225.         struct Draw : public Base
  226.         {
  227.             uint32 count;
  228.  
  229.             static inline void ExecuteBackend(const Draw* params)
  230.             {
  231.             }
  232.         };
  233.  
  234.         union AllPackets
  235.         {
  236.         public:
  237.             BackendFunction execute;
  238.  
  239.         private:
  240.             Base Base;
  241.             BindShader BindProgram;
  242.             BindVertexArray BindVertexArray;
  243.             Draw DrawArrays;
  244.         };
  245.     }
  246.  
  247.     struct CommandBucket
  248.     {
  249.  
  250.         CommandBucket()
  251.             : maxPackets(0),
  252.             packets(nullptr)
  253.         {
  254.             packetCount = 0;
  255.         }
  256.  
  257.         ~CommandBucket()
  258.         {
  259.             delete[] packets;
  260.             packets = nullptr;
  261.             maxPackets = 0;
  262.         }
  263.  
  264.         void Init()
  265.         {
  266.             maxPackets = 10 * 1024 * 1024;
  267.             packetCount = 0;
  268.             packets = new packet::AllPackets[maxPackets];
  269.             memset(packets, 0, maxPackets * sizeof(packet::AllPackets));
  270.         }
  271.  
  272.         void Clear()
  273.         {
  274.             packetCount = 0;
  275.         }
  276.  
  277.         void Submit()
  278.         {
  279.             const packet::AllPackets* pPacket;
  280.  
  281.             if(!packetCount)
  282.                 return;
  283.  
  284.             for(pPacket = packets; pPacket->execute != nullptr; pPacket++) {
  285.                 pPacket->execute((packet::Base*)pPacket);
  286.             }
  287.         }
  288.  
  289.         inline void BindProgram(uint32 program)
  290.         {
  291.             packet::BindShader* pPacket = NextPacket<packet::BindShader>();
  292.  
  293.             pPacket->backendFunction = packet::BackendFunction(packet::BindShader::ExecuteBackend);
  294.             pPacket->program = program;
  295.         }
  296.  
  297.         inline void BindVertexArray(uint32 vao)
  298.         {
  299.             packet::BindVertexArray* pPacket = NextPacket<packet::BindVertexArray>();
  300.  
  301.             pPacket->backendFunction = packet::BackendFunction(packet::BindVertexArray::ExecuteBackend);
  302.             pPacket->vao = vao;
  303.         }
  304.  
  305.         inline void DrawArrays(uint32 count)
  306.         {
  307.             packet::Draw* pPacket = NextPacket<packet::Draw>();
  308.  
  309.             pPacket->backendFunction = packet::BackendFunction(packet::Draw::ExecuteBackend);
  310.             pPacket->count = count;
  311.         }
  312.  
  313.     private:
  314.         unsigned int maxPackets;
  315.         packet::AllPackets* packets;
  316.         unsigned int packetCount;
  317.  
  318.         template <typename T>
  319.         T* NextPacket() { return reinterpret_cast<T*>(&packets[packetCount++]); }
  320.     };
  321. }
  322.  
  323. int main()
  324. {
  325.     Timer::Init();
  326.  
  327.     MyQueue::CommandBucket myQueue;
  328.     myQueue.Init(10 * 1024 * 1024);
  329.  
  330.     Timer::Reset();
  331.     for(int i = 0; i < 40000; ++i) {
  332.         myQueue.DrawArrays(5);
  333.     }
  334.     std::cout << "myQueue: adding 40k draw commands took " << Timer::ElapsedMillis() << "ms\n";
  335.  
  336.     Timer::Reset();
  337.     myQueue.Submit();
  338.     std::cout << "myQueue: submitting 40k draw commands took " << Timer::ElapsedMillis() << "ms\n";
  339.  
  340.     mole::CommandBucket molecularQueue;
  341.     Timer::Reset();
  342.     for(int i = 0; i < 40000; ++i) {
  343.         mole::Commands::Draw* draw = molecularQueue.AddCommand<mole::Commands::Draw>();
  344.         draw->vertexCount = 5;
  345.     }
  346.     std::cout << "molecularQueue: adding 40k draw commands took " << Timer::ElapsedMillis() << "ms\n";
  347.  
  348.     Timer::Reset();
  349.     molecularQueue.Submit();
  350.     std::cout << "molecularQueue: submitting 40k draw commands took " << Timer::ElapsedMillis() << "ms\n";
  351.  
  352.     return 0;
  353. }
RAW Paste Data