Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "glcommon.h"
- #include "glcontext.h"
- #include "glbuffer.h"
- #include "glstatetracker.h"
- #include <iostream>
- #include <thread>
- #include <chrono>
- #include <fstream>
- #include <chrono>
- #include <random>
- template <typename tContainer>
- void gen_random_values(std::uint32_t count, tContainer& dst, float low, float high, int seed)
- {
- std::mt19937 rng;
- rng.seed(seed);
- std::uniform_real_distribution<float> distr(low,high);
- for(std::uint32_t i = 0; i < count; ++i)
- {
- dst.push_back(distr(rng));
- }
- }
- int main(int, char**)
- {
- try
- {
- GLContextCreationInfo cci;
- cci.glVersion = GLV_4_3; // Up to 4.5. Sadly, AMD drivers don't reach yet.
- std::shared_ptr<GLContext> pContext = GLContext_New(cci);
- if(!pContext)
- return 1;
- const std::uint32_t iter_count = 1;
- std::cout << "Running " << iter_count << " test iteration/s..." << std::endl;
- std::ifstream cshader("input.txt");
- std::string str;
- std::string l;
- while(std::getline(cshader,l)) { str+=l; str += '\n'; l.clear(); }
- std::shared_ptr<GLFunctions> pFunctions = pContext->GetFunctions().lock();
- GLStateTracker& Tracker = *pContext->GetStates();
- std::vector<GLfloat> src_a;
- std::vector<GLfloat> src_b;
- std::vector<GLfloat> dst;
- std::vector<GLfloat> cpu_dst;
- gen_random_values(0xFFFF,src_a,0.f,500.f,42);
- gen_random_values(0xFFFF,src_b,0.f,500.f,53);
- GLuint length = std::min(src_a.size(),src_b.size());
- {
- dst.resize(length);
- cpu_dst.resize(length);
- }
- GLShader computeShader(glppH(pContext),ST_COMPUTE_SHADER);
- {
- computeShader.glppShaderSource(str);
- std::string result;
- bool rv = computeShader.glppCompile(&result);
- if(!rv)
- {
- std::cout << std::endl << "Shader Compilation Failed: "
- << std::endl << result << std::endl;
- return 1;
- }
- }
- GLBuffer destBuffer(glppH(pContext));
- {
- Tracker.BufferState().BindBuffer(destBuffer,BBT_SHADER_STORAGE_BUFFER);
- Tracker.BufferState().BufferData(BBT_SHADER_STORAGE_BUFFER,
- sizeof(GLint)*length,0,MUH_STATIC_READ);
- }
- GLBuffer srcA_Buffer(glppH(pContext));
- {
- Tracker.BufferState().BindBuffer(srcA_Buffer,BBT_SHADER_STORAGE_BUFFER);
- Tracker.BufferState().BufferData(BBT_SHADER_STORAGE_BUFFER,
- sizeof(GLint)*length,src_a.data(),MUH_STREAM_READ);
- }
- GLBuffer srcB_Buffer(glppH(pContext));
- {
- Tracker.BufferState().BindBuffer(srcB_Buffer,BBT_SHADER_STORAGE_BUFFER);
- Tracker.BufferState().BufferData(BBT_SHADER_STORAGE_BUFFER,
- sizeof(GLint)*length,src_b.data(),MUH_STREAM_READ);
- }
- GLProgram computeProgram(glppH(pContext));
- {
- computeProgram.AttachShader(computeShader);
- std::string result;
- bool rv = computeProgram.glppLinkProgram(&result);
- if(!rv)
- {
- std::cout << std::endl << "Program Linking Failed: "
- << std::endl << result << std::endl;
- return 1;
- }
- }
- // Get Ready
- {
- Tracker.BufferState().BindBufferBase(destBuffer,BBTI_SHADER_STORAGE_BUFFER,0);
- Tracker.BufferState().BindBufferBase(srcA_Buffer,BBTI_SHADER_STORAGE_BUFFER,1);
- Tracker.BufferState().BindBufferBase(srcB_Buffer,BBTI_SHADER_STORAGE_BUFFER,2);
- computeProgram.ShaderStorageBlockBinding(0,0);
- computeProgram.ShaderStorageBlockBinding(1,1);
- computeProgram.ShaderStorageBlockBinding(2,2);
- computeProgram.ProgramUniform1ui(computeProgram.GetUniformLocation("length"),length);
- Tracker.ProgramState().UseProgram(computeProgram);
- }
- auto compute_start = std::chrono::high_resolution_clock::now();
- // Begin Compute
- {
- for(std::uint32_t iter = 0; iter < iter_count; ++iter)
- {
- pFunctions->glDispatchCompute(1,1,1);
- GLContext::CheckErrors(*pFunctions,"DispatchCompute"); // Check for errors.
- // If an error occurs, it's "DispatchCompute" 's fault.
- // Errors are not checked automatically for raw function calls.
- }
- }
- // Read back
- if(length)
- {
- Tracker.BufferState().BindBuffer(destBuffer,BBT_SHADER_STORAGE_BUFFER);
- GLvoid* d = Tracker.BufferState().MapBuffer(BBT_SHADER_STORAGE_BUFFER,MMSB_READ_ONLY);
- memcpy(dst.data(),d,sizeof(GLint)*dst.size());
- Tracker.BufferState().UnmapBuffer(BBT_SHADER_STORAGE_BUFFER);
- }
- auto compute_end = std::chrono::high_resolution_clock::now(); // compute_end is taken now, since
- // DispatchCompute may be delaying computation until later time.
- // Alternatively, a glFinish call after DispatchCompute may work as well.
- auto cpu_compute_start = std::chrono::high_resolution_clock::now();
- for(std::uint32_t iter = 0; iter < iter_count; ++iter)
- {
- for(std::uint32_t i = 0; i < cpu_dst.size(); ++i)
- {
- cpu_dst[i] =
- std::sqrt((std::sqrt(src_a[i])*std::sqrt(src_b[i]))
- * std::sqrt(src_a[i]*src_b[i]));
- }
- }
- auto cpu_compute_end = std::chrono::high_resolution_clock::now();
- std::cout << "GPU Computation Time: "
- << std::chrono::duration_cast<std::chrono::microseconds>
- (compute_end-compute_start).count()
- << "us" << std::endl;
- std::cout << "CPU Computation Time: "
- << std::chrono::duration_cast<std::chrono::microseconds>
- (cpu_compute_end-cpu_compute_start).count()
- << "us" << std::endl;
- std::cout << "Computed values: " << std::endl;
- for(std::uint32_t i = 0; i < std::min<std::uint32_t>(dst.size(),16); ++i)
- {
- std::cout << "\t" << src_a[i] << " ~ " << src_b[i] << " = "
- << dst[i] << " (" << cpu_dst[i] << ")" << std::endl;
- if(i && (i%5)==0)
- std::cout << std::endl;
- }
- while(pContext->Update())
- {
- pContext->Begin();
- pFunctions->glClearColor(1,1,1,1);
- pFunctions->glClear(GL_COLOR_BUFFER_BIT);
- pContext->End();
- }
- }
- catch(GlException& e)
- {
- std::cout << std::endl << "Unhandled GL Exception: " << e.what()
- << " (Error ID: " << GLContext::ErrorName(e.error()) << ")" << std::endl;
- return 1;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement