Advertisement
Guest User

Untitled

a guest
Nov 13th, 2019
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.35 KB | None | 0 0
  1. #include <iostream>
  2. #include <functional>
  3. #include <glew.h>
  4. #include <memory>
  5. #include <SDL.h>
  6.  
  7. static int allocCount = 0;
  8.  
  9. void* operator new(size_t size)
  10. {
  11.     ++allocCount;
  12.     return malloc(size);
  13. }
  14.  
  15. typedef unsigned long long uint;
  16. typedef unsigned char uchar;
  17.  
  18. class RenderCommandQueue
  19. {
  20. public:
  21.     using RenderCommandFn = std::function<void()>;
  22.  
  23.     RenderCommandQueue();
  24.     ~RenderCommandQueue() = default;
  25.  
  26.     void* Allocate(RenderCommandFn func, uint size);
  27.  
  28.     void Execute();
  29.  
  30. private:
  31.     std::unique_ptr<uchar[]> commandBuffer = nullptr;
  32.     uchar* commandBufferPtr = nullptr;
  33.     uint commandCount = 0;
  34. };
  35.  
  36. RenderCommandQueue::RenderCommandQueue()
  37. {
  38.     commandBuffer = std::make_unique<uchar[]>(10 * 1024 * 1024);
  39.     commandBufferPtr = commandBuffer.get();
  40. }
  41.  
  42. void* RenderCommandQueue::Allocate(RenderCommandFn fn, uint size)
  43. {
  44.     // TODO: alignment
  45.     *(RenderCommandFn*)commandBufferPtr = fn;
  46.     commandBufferPtr += sizeof(RenderCommandFn);
  47.  
  48.     *(uint*)commandBufferPtr = size;
  49.     commandBufferPtr += sizeof(uint);
  50.  
  51.     void* memory = commandBufferPtr;
  52.     commandBufferPtr += size;
  53.  
  54.     commandCount++;
  55.     return memory;
  56. }
  57.  
  58. void RenderCommandQueue::Execute()
  59. {
  60.     uchar* buffer = commandBuffer.get();
  61.     for (uint i = 0; i < commandCount; i++) {
  62.         RenderCommandFn function = *(RenderCommandFn*)buffer;
  63.         buffer += sizeof(RenderCommandFn);
  64.  
  65.         uint size = *(uint*)buffer;
  66.         buffer += sizeof(uint);
  67.         function();
  68.         buffer += size;
  69.     }
  70.  
  71.     commandBufferPtr = commandBuffer.get();
  72.     commandCount = 0;
  73. }
  74.  
  75. static RenderCommandQueue queue;
  76.  
  77. using RenderCommandFn = std::function<void()>;
  78. static void* Submit(RenderCommandFn fn, unsigned int size)
  79. {
  80.     return queue.Allocate(fn, size);
  81. }
  82.  
  83. void PushRenderCmd(RenderCommandFn fn)
  84. {
  85.     auto mem = Submit(fn, sizeof(RenderCommandFn));
  86. }
  87.  
  88. struct Vertex
  89. {
  90.     float x, y;
  91.     float u, v;
  92. };
  93.  
  94. int main(int argc, char* args[])
  95. {
  96.     //RenderCommandQueue does first allocation -> count = 1
  97.  
  98.     SDL_Window* window = SDL_CreateWindow("window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_OPENGL);
  99.     SDL_GLContext glContext = SDL_GL_CreateContext(window);
  100.  
  101.     glewExperimental = true;
  102.     glewInit();
  103.  
  104.     //Second allocation -> count = 2
  105.     std::vector<Vertex> vertices;
  106.     //Third allocation -> count = 3
  107.     vertices.resize(60000);
  108.  
  109.     float r = 0.2f;
  110.     float g = 0.2f;
  111.  
  112.     //No allocation -> count = 3
  113.     PushRenderCmd([=](){
  114.         glClearColor(r, g, 0.2f, 1.0f);
  115.         glClear(GL_COLOR_BUFFER_BIT);
  116.     });
  117.  
  118.     //No allocation -> count = 3
  119.     GLuint vao;
  120.     PushRenderCmd([&vao]() {
  121.         glCreateVertexArrays(1, &vao);
  122.         glBindVertexArray(vao);
  123.     });
  124.  
  125.     GLuint vbo;
  126.     //Fourth allocation -> count = 4
  127.     void* ptr = new void* [512];
  128.  
  129.     //No allocation -> count = 4
  130.     PushRenderCmd([&]() {
  131.         glCreateBuffers(1, &vbo);
  132.         glBindBuffer(GL_ARRAY_BUFFER, vbo);
  133.  
  134.         //No allocation -> count = 4
  135.         glNamedBufferData(vbo, 512, ptr, GL_DYNAMIC_DRAW);
  136.  
  137.         delete[] ptr;
  138.     });
  139.  
  140.     //Fifth allocation -> count = 5
  141.     void* ptr2 = new void* [vertices.size()];
  142.     std::memcpy(ptr2, vertices.data(), vertices.size());
  143.     GLuint vbo2;
  144.     //No allocation -> count = 5
  145.     PushRenderCmd([&]() {
  146.         glCreateBuffers(1, &vbo2);
  147.         glBindBuffer(GL_ARRAY_BUFFER, vbo2);
  148.  
  149.         //No allocation -> count = 5
  150.         glNamedBufferData(vbo2, vertices.size(), ptr2, GL_DYNAMIC_DRAW);
  151.  
  152.         delete[] ptr2;
  153.     });
  154.  
  155.     queue.Execute();
  156.  
  157.     std::cout << allocCount << std::endl;
  158.  
  159.     return 0;
  160. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement