diff --git a/src/GLWidget.cpp b/src/GLWidget.cpp index c5b5ca7..c46b66c 100644 --- a/src/GLWidget.cpp +++ b/src/GLWidget.cpp @@ -9,6 +9,7 @@ #include "Overlay.h" #include #include "FPS.h" +#include "Pendulum.h" GLWidget::GLWidget(Simulation * simulation) : simulation(simulation) { startTimer(1000 / 144); @@ -186,6 +187,7 @@ void GLWidget::uploadStaticDataToGPU() { } void GLWidget::changePosition() { + auto t1 = system_clock::now(); glBindBuffer(GL_ARRAY_BUFFER, positionVBO); auto positions = (GLfloat*) glMapBufferRange(GL_ARRAY_BUFFER, 0, GLsizeiptr(positionCount * sizeof(float)), GL_MAP_WRITE_BIT); size_t index = 0; @@ -198,6 +200,7 @@ void GLWidget::changePosition() { } } glUnmapBuffer(GL_ARRAY_BUFFER); + // std::cout << duration_cast(system_clock::now() - t1).count() << std::endl; simulation->semaphore.release(); } diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 7105cb6..3abe412 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -17,6 +17,7 @@ #include #include #include "Overlay.h" +#include "Slider.h" MainWindow::MainWindow() { simulationThread = new QThread(this); diff --git a/src/MainWindow.h b/src/MainWindow.h index b61bc53..c69fcdd 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -1,11 +1,12 @@ #include #include -#include "Slider.h" #include "Pendulum.h" class Simulation; class QGridLayout; class GLWidget; +template + class Slider; enum Property {Angle, Mass, Length}; @@ -38,7 +39,7 @@ private: QGridLayout * segmentGrid {}; Slider * gravitySlider = nullptr, * timescaleSlider = nullptr; - Slider<> * substepsSlider = nullptr; + Slider * substepsSlider = nullptr; signals: void pendulaCreated(const std::vector &add); diff --git a/src/Simulation.cpp b/src/Simulation.cpp index 2a234e0..86ebab4 100644 --- a/src/Simulation.cpp +++ b/src/Simulation.cpp @@ -5,6 +5,7 @@ #include #include #include "FPS.h" +#include "Pendulum.h" #include #include #include @@ -12,7 +13,6 @@ Simulation::Simulation() { ups = new FPS; ups->setUpdateInterval(100); - timer = new QTimer(this); QTimer::connect(timer, &QTimer::timeout, this, &Simulation::update); timer->setInterval(updateInterval); @@ -33,19 +33,23 @@ void Simulation::initialize() { initializeOpenGLFunctions(); } - int maxWorkGroupCount[3]; - int maxWorkGroupSize[3]; - int maxWorkGroupInvocations; - for (int i = 0; i < 3; i++){ - glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, i, maxWorkGroupCount + i); - glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, i, maxWorkGroupSize + i); + // Read GPU Limits + { + for (int i = 0; i < 3; i++){ + glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, i, gpuLimits.maxWGCount + i); + glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, i, gpuLimits.maxWGSize + i); + } + glGetIntegerv(GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS, &gpuLimits.maxWGInvocations); + + printf("Max work group count: (%d, %d, %d)\n", gpuLimits.maxWGCount[0], gpuLimits.maxWGCount[1], gpuLimits.maxWGCount[2]); + printf("Max work group size: (%d, %d, %d)\n", gpuLimits.maxWGSize[0], gpuLimits.maxWGSize[1], gpuLimits.maxWGSize[2]); + printf("Max work group invocations (x * y * z): %d\n", gpuLimits.maxWGInvocations); } - glGetIntegerv(GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS, &maxWorkGroupInvocations); + // Shader + { - printf("Max work group count: (%d, %d, %d)\n", maxWorkGroupCount[0], maxWorkGroupCount[1], maxWorkGroupCount[2]); - printf("Max work group size: (%d, %d, %d)\n", maxWorkGroupSize[0], maxWorkGroupSize[1], maxWorkGroupSize[2]); - printf("Max work group invocations (x * y * z): %d\n", maxWorkGroupInvocations); + } } @@ -62,18 +66,30 @@ void Simulation::update() { double newPotentialEnergy = 0; double newKineticEnergy = 0; - #pragma omp parallel for - for (int i = 0; i < pendula.size(); i++){ // NOLINT(*-loop-convert) // not ranged based for msvc - for (int k = 0; k < substeps; k++) - pendula[i]->update(h, gravity); - double localPotentialEnergy = pendula[i]->potentialEnergy(gravity); - double localKineticEnergy = pendula[i]->kineticEnergy(); - #pragma omp atomic - newPotentialEnergy += localPotentialEnergy; - #pragma omp atomic - newKineticEnergy += localKineticEnergy; + + + // OLD with CPUs + { + + #pragma omp parallel for + for (int i = 0; i < pendula.size(); i++){ // NOLINT(*-loop-convert) // not ranged based for msvc + for (int k = 0; k < substeps; k++) + pendula[i]->update(h, gravity); + double localPotentialEnergy = pendula[i]->potentialEnergy(gravity); + double localKineticEnergy = pendula[i]->kineticEnergy(); + #pragma omp atomic + newPotentialEnergy += localPotentialEnergy; + #pragma omp atomic + newKineticEnergy += localKineticEnergy; + } } + // NEW with GPUs + { + + } + + potentialEnergy = newPotentialEnergy; kineticEnergy = newKineticEnergy; @@ -92,6 +108,7 @@ void Simulation::clearPendula() { pendula.shrink_to_fit(); updateEnergy(); + updateGPUData(); emit layoutChanged(); } @@ -103,6 +120,7 @@ void Simulation::addPendula(const std::vector &add) { pendula.push_back(p); updateEnergy(); + updateGPUData(); emit layoutChanged(); } @@ -115,3 +133,7 @@ void Simulation::updateEnergy() { } } +void Simulation::updateGPUData() { + +} + diff --git a/src/Simulation.h b/src/Simulation.h index c106e13..726da3f 100644 --- a/src/Simulation.h +++ b/src/Simulation.h @@ -2,12 +2,12 @@ #include #include #include -#include "Pendulum.h" #include #include -class QTimer; class FPS; +class Pendulum; +class QOpenGLShaderProgram; class Simulation : public QObject, protected QOpenGLFunctions_4_3_Core { Q_OBJECT @@ -40,6 +40,13 @@ public slots: private slots: void update(); private: + void updateGPUData(); + struct GPULimits { + int maxWGCount[3]; + int maxWGSize[3]; + int maxWGInvocations; + } gpuLimits; + QOpenGLShaderProgram * program; QTimer * timer; int updateInterval = 16; }; \ No newline at end of file diff --git a/src/Slider.h b/src/Slider.h index 2fcc80b..873c0ab 100644 --- a/src/Slider.h +++ b/src/Slider.h @@ -1,3 +1,5 @@ +#pragma once + #include #include #include