diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 1ff0c42..0000000 --- a/.gitattributes +++ /dev/null @@ -1,63 +0,0 @@ -############################################################################### -# Set default behavior to automatically normalize line endings. -############################################################################### -* text=auto - -############################################################################### -# Set default behavior for command prompt diff. -# -# This is need for earlier builds of msysgit that does not have it on by -# default for csharp files. -# Note: This is only used by command line -############################################################################### -#*.cs diff=csharp - -############################################################################### -# Set the merge driver for project and solution files -# -# Merging from the command prompt will add diff markers to the files if there -# are conflicts (Merging from VS is not affected by the settings below, in VS -# the diff markers are never inserted). Diff markers may cause the following -# file extensions to fail to load in VS. An alternative would be to treat -# these files as binary and thus will always conflict and require user -# intervention with every merge. To do so, just uncomment the entries below -############################################################################### -#*.sln merge=binary -#*.csproj merge=binary -#*.vbproj merge=binary -#*.vcxproj merge=binary -#*.vcproj merge=binary -#*.dbproj merge=binary -#*.fsproj merge=binary -#*.lsproj merge=binary -#*.wixproj merge=binary -#*.modelproj merge=binary -#*.sqlproj merge=binary -#*.wwaproj merge=binary - -############################################################################### -# behavior for image files -# -# image files are treated as binary by default. -############################################################################### -#*.jpg binary -#*.png binary -#*.gif binary - -############################################################################### -# diff behavior for common document formats -# -# Convert binary document formats to text before diffing them. This feature -# is only available from the command line. Turn it on by uncommenting the -# entries below. -############################################################################### -#*.doc diff=astextplain -#*.DOC diff=astextplain -#*.docx diff=astextplain -#*.DOCX diff=astextplain -#*.dot diff=astextplain -#*.DOT diff=astextplain -#*.pdf diff=astextplain -#*.PDF diff=astextplain -#*.rtf diff=astextplain -#*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore index b06e864..7d93a0c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,212 +1,47 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. - -# User-specific files -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -build/ -bld/ -[Bb]in/ -[Oo]bj/ - -# Visual Studio 2015 cache/options directory -.vs/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUNIT -*.VisualState.xml -TestResult.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# DNX -project.lock.json -artifacts/ - -*_i.c -*_p.c -*_i.h -*.ilk -*.meta -*.obj -*.pch -*.pdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj +# Compiled source # +################### +*.com +*.class +*.dll +*.exe +*.o +*.so + +# Packages # +############ +# it's better to unpack these files and commit the raw source +# git has its own built in compression methods +*.7z +*.dmg +*.gz +*.iso +*.jar +*.rar +*.tar +*.zip + +# Logs and databases # +###################### *.log -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opensdf -*.sdf -*.cachefile - -# Visual Studio profiler -*.psess -*.vsp -*.vspx - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# JustCode is a .NET coding add-in -.JustCode - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# NCrunch -_NCrunch_* -.*crunch*.local.xml - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -## TODO: Comment the next line if you want to checkin your -## web deploy settings but do note that will include unencrypted -## passwords -#*.pubxml - -*.publishproj - -# NuGet Packages -*.nupkg -# The packages folder can be ignored because of Package Restore -**/packages/* -# except build/, which is used as an MSBuild target. -!**/packages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/packages/repositories.config - -# Windows Azure Build Output -csx/ -*.build.csdef - -# Windows Store app package directory -AppPackages/ - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!*.[Cc]ache/ - -# Others -ClientBin/ -[Ss]tyle[Cc]op.* -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.pfx -*.publishsettings -node_modules/ -orleans.codegen.cs - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm - -# SQL Server files -*.mdf -*.ldf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings - -# Microsoft Fakes -FakesAssemblies/ - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -# LightSwitch generated files -GeneratedArtifacts/ -_Pvt_Extensions/ -ModelManifest.xml +*.sql +*.sqlite + +# OS generated files # +###################### +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# CMake Generated Files # +######################### +CMakeCache.txt +CMakeFiles +CMakeScripts +Makefile +cmake_install.cmake +install_manifest.txt +CTestTestfile.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..b8997c8 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,101 @@ +# Check versions +message(STATUS "CMake version: ${CMAKE_VERSION}") +cmake_minimum_required(VERSION 3.1) + +set_property(GLOBAL PROPERTY USE_FOLDERS ON) + +# Set the project name +set(PNAME Conways) +project(${PNAME}) + +# Set up variables, and find SFML +if (WIN32) + set(SFML_ROOT root CACHE STRING "User specified path") + set(SFML_INCLUDE_DIR ${SFML_ROOT}/include) +endif() + +set(SFML_COMPONENTS graphics window system network audio) +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) +find_package(SFML 2.1 COMPONENTS ${SFML_COMPONENTS} REQUIRED) +message(STATUS "SFML found: ${SFML_FOUND}") + +# Find OpenCL +find_package( OpenCL REQUIRED ) +message(STATUS "OpenCL found: ${OPENCL_FOUND}") + +# Find OpenGL +find_package( OpenGL REQUIRED) +message(STATUS "OpenGL found: ${OPENGL_FOUND}") + +# Include the directories for the main program, GL, CL and SFML's headers +include_directories(${SFML_INCLUDE_DIR}) +include_directories(${OpenCL_INCLUDE_DIRS}) +include_directories(include) + +# Glob all thr sources into their values +file(GLOB_RECURSE SOURCES "src/*.cpp") +file(GLOB_RECURSE HEADERS "include/*.h" "include/*.hpp") +file(GLOB_RECURSE KERNELS "kernels/*.cl") + +add_executable(${PNAME} ${SOURCES} ${HEADERS} ${KERNELS}) + +# Follow the sub directory structure to add sub-filters in VS +# Gotta do it one by one unfortunately + +foreach (source IN ITEMS ${SOURCES}) + if (IS_ABSOLUTE "${source}") + + get_filename_component(filename ${source} DIRECTORY) + + STRING(REGEX REPLACE "/" "\\\\" filename ${filename}) + + string(REGEX MATCHALL "src(.*)" substrings ${filename}) + list(GET substrings 0 substring) + + SOURCE_GROUP(${substring} FILES ${source}) + + endif() +endforeach() + +foreach (source IN ITEMS ${HEADERS}) + if (IS_ABSOLUTE "${source}") + + get_filename_component(filename ${source} DIRECTORY) + + STRING(REGEX REPLACE "/" "\\\\" filename ${filename}) + + string(REGEX MATCHALL "include(.*)" substrings ${filename}) + list(GET substrings 0 substring) + + SOURCE_GROUP(${substring} FILES ${source}) + + endif() +endforeach() + +foreach (source IN ITEMS ${KERNELS}) + if (IS_ABSOLUTE "${source}") + + get_filename_component(filename ${source} DIRECTORY) + + STRING(REGEX REPLACE "/" "\\\\" filename ${filename}) + + string(REGEX MATCHALL "kernels(.*)" substrings ${filename}) + list(GET substrings 0 substring) + + SOURCE_GROUP(${substring} FILES ${source}) + + endif() +endforeach() + +# Link CL, GL, and SFML +target_link_libraries (${PNAME} ${SFML_LIBRARIES} ${SFML_DEPENDENCIES}) +target_link_libraries (${PNAME} ${OpenCL_LIBRARY}) +target_link_libraries (${PNAME} ${OPENGL_LIBRARIES}) + +if (NOT WIN32) + target_link_libraries (${PNAME} -lpthread) +endif() + +# Setup to use C++14 +set_property(TARGET ${PNAME} PROPERTY CXX_STANDARD 14) + diff --git a/Conway_OpenCL.sln b/Conway_OpenCL.sln deleted file mode 100644 index fff863d..0000000 --- a/Conway_OpenCL.sln +++ /dev/null @@ -1,28 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.23107.0 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Conway_OpenCL", "Conway_OpenCL\Conway_OpenCL.vcxproj", "{000000DA-0000-0000-0000-000000000000}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {000000DA-0000-0000-0000-000000000000}.Debug|x64.ActiveCfg = Debug|x64 - {000000DA-0000-0000-0000-000000000000}.Debug|x64.Build.0 = Debug|x64 - {000000DA-0000-0000-0000-000000000000}.Debug|x86.ActiveCfg = Debug|Win32 - {000000DA-0000-0000-0000-000000000000}.Debug|x86.Build.0 = Debug|Win32 - {000000DA-0000-0000-0000-000000000000}.Release|x64.ActiveCfg = Release|x64 - {000000DA-0000-0000-0000-000000000000}.Release|x64.Build.0 = Release|x64 - {000000DA-0000-0000-0000-000000000000}.Release|x86.ActiveCfg = Release|Win32 - {000000DA-0000-0000-0000-000000000000}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/Conway_OpenCL/Conway.hpp b/Conway_OpenCL/Conway.hpp deleted file mode 100644 index 3669fb8..0000000 --- a/Conway_OpenCL/Conway.hpp +++ /dev/null @@ -1,395 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "Shader.hpp" - -#define SUCCESS 0 -#define FAILURE 1 - -float elap_time() { - static __int64 start = 0; - static __int64 frequency = 0; - - if (start == 0) { - QueryPerformanceCounter((LARGE_INTEGER*)&start); - QueryPerformanceFrequency((LARGE_INTEGER*)&frequency); - return 0.0f; - } - - __int64 counter = 0; - QueryPerformanceCounter((LARGE_INTEGER*)&counter); - return (float)((counter - start) / double(frequency)); -} - -// convert the kernel file into a string -int convertToString(const char *filename, std::string& s) -{ - size_t size; - char* str; - std::fstream f(filename, (std::fstream::in | std::fstream::binary)); - - if(f.is_open()) - { - size_t fileSize; - f.seekg(0, std::fstream::end); - size = fileSize = (size_t)f.tellg(); - f.seekg(0, std::fstream::beg); - str = new char[size+1]; - if(!str) - { - f.close(); - return 0; - } - - f.read(str, fileSize); - f.close(); - str[size] = '\0'; - s = str; - delete[] str; - return 0; - } - std::cout << "Error: failed to open file\n:" << filename << std::endl; - return FAILURE; -} - -void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode) { - if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) - glfwSetWindowShouldClose(window, GL_TRUE); -} - -int main(int argc, char* argv[]) -{ - int WINDOW_X = 1000; - int WINDOW_Y = 1000; - int GRID_WIDTH = WINDOW_X; - int GRID_HEIGHT = WINDOW_Y; - int WORKER_SIZE = 1000; - - // ======================================= Setup OpenGL ======================================================= - - glfwInit(); - - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); - - GLFWwindow* gl_window = glfwCreateWindow(GRID_WIDTH, GRID_HEIGHT, "GPU accelerated life", nullptr, nullptr); - glfwMakeContextCurrent(gl_window); - - glfwSetKeyCallback(gl_window, key_callback); - - glewExperimental = GL_TRUE; - glewInit(); - - glViewport(0, 0, GRID_WIDTH, GRID_HEIGHT); - - glClearColor(0.2f, 0.3f, 0.3f, 1.0f); - - // Stolen from LearnOpenGL, aint got no time for that - Shader vert_frag_shaders("Z:\\VS_Projects\\Conway_OpenCL\\Conway_OpenCL\\vertex_shader.sh", "Z:\\VS_Projects\\Conway_OpenCL\\Conway_OpenCL\\fragment_shader.sh"); - - GLfloat vertices[] = { - // Positions // Colors // Texture Coords - 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, // Top Right - 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // Bottom Right - -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, // Bottom Left - -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f // Top Left - }; - GLuint indices[] = { - 0, 1, 3, // First Triangle - 1, 2, 3 // Second Triangle - }; - - GLuint VBO, VAO, EBO; - glGenVertexArrays(1, &VAO); - glGenBuffers(1, &VBO); - glGenBuffers(1, &EBO); - - // Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s). - glBindVertexArray(VAO); - - glBindBuffer(GL_ARRAY_BUFFER, VBO); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); - - - // Position attribute - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0); - glEnableVertexAttribArray(0); - // Color attribute - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); - glEnableVertexAttribArray(1); - // TexCoord attribute - glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat))); - glEnableVertexAttribArray(2); - - glBindVertexArray(0); // Unbind VAO - - // ============================== OpenCL Setup ================================================================== - - // Get the platforms - cl_uint numPlatforms; - cl_platform_id platform = NULL; - cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms); // Retrieve the number of platforms - if (status != CL_SUCCESS) { - std::cout << "Error: Getting platforms!" << std::endl; - return FAILURE; - } - - // Choose the first available platform - if(numPlatforms > 0) { - cl_platform_id* platforms = new cl_platform_id[numPlatforms]; - status = clGetPlatformIDs(numPlatforms, platforms, NULL); // Now populate the array with the platforms - platform = platforms[0]; - delete platforms; - } - - cl_uint numDevices = 0; - cl_device_id *devices; - status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, NULL, &numDevices); - if (numDevices == 0) { //no GPU available. - std::cout << "No GPU device available." << std::endl; - std::cout << "Choose CPU as default device." << std::endl; - status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, 0, NULL, &numDevices); - devices = new cl_device_id[numDevices]; - status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, numDevices, devices, NULL); - } - else { - devices = new cl_device_id[numDevices]; - status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, numDevices, devices, NULL); - } - - HGLRC hGLRC = wglGetCurrentContext(); - HDC hDC = wglGetCurrentDC(); - cl_context_properties cps[] ={CL_CONTEXT_PLATFORM, (cl_context_properties)platform, CL_GL_CONTEXT_KHR, (cl_context_properties)hGLRC, CL_WGL_HDC_KHR, (cl_context_properties)hDC, 0 }; - - - cl_context context = clCreateContext(cps, 1, devices,NULL,NULL,NULL); - cl_command_queue commandQueue = clCreateCommandQueue(context, devices[0], 0, NULL); - - - // ============================== Kernel Compilation, Setup ==================================================== - - // Read the kernel from the file to a string - const char *compute_kernel_filename = "Z:\\VS_Projects\\Conway_OpenCL\\Conway_OpenCL\\conway_compute.cl"; - const char *align_kernel_filename = "Z:\\VS_Projects\\Conway_OpenCL\\Conway_OpenCL\\conway_align.cl"; - - std::string compute_kernel_string; - std::string align_kernel_string; - - convertToString(compute_kernel_filename, compute_kernel_string); - convertToString(align_kernel_filename, align_kernel_string); - - // Create a program with the source - const char *compute_source = compute_kernel_string.c_str(); - const char *align_source = align_kernel_string.c_str(); - - size_t compute_source_size[] = {strlen(compute_source)}; - size_t align_source_size[] = { strlen(align_source) }; - - cl_program compute_program = clCreateProgramWithSource(context, 1, &compute_source, compute_source_size, NULL); - cl_program align_program = clCreateProgramWithSource(context, 1, &align_source, align_source_size, NULL); - - // Build the compute program - status = clBuildProgram(compute_program, 1, devices, NULL, NULL, NULL); - - if (status == CL_BUILD_PROGRAM_FAILURE) { - - size_t log_size; - clGetProgramBuildInfo(compute_program, devices[0], CL_PROGRAM_BUILD_LOG, 0, NULL, &log_size); - char *log = new char[log_size]; - - clGetProgramBuildInfo(compute_program, devices[0], CL_PROGRAM_BUILD_LOG, log_size, log, NULL); - - std::cout << log << std::endl; - } - - // Build the align program - status = clBuildProgram(align_program, 1, devices, NULL, NULL, NULL); - - if (status == CL_BUILD_PROGRAM_FAILURE) { - - size_t log_size; - clGetProgramBuildInfo(align_program, devices[0], CL_PROGRAM_BUILD_LOG, 0, NULL, &log_size); - char *log = new char[log_size]; - - clGetProgramBuildInfo(align_program, devices[0], CL_PROGRAM_BUILD_LOG, log_size, log, NULL); - - std::cout << log << std::endl; - } - - // Now create the kernels - cl_kernel compute_kernel = clCreateKernel(compute_program, "conway_compute", NULL); - cl_kernel align_kernel = clCreateKernel(align_program, "conway_align", NULL); - - - - // ======================================= Setup grid ========================================================= - - // Setup the rng - std::mt19937 rng(time(NULL)); - std::uniform_int_distribution rgen(0, 4); // 25% chance - - // Init the grids - unsigned char* node_grid = new unsigned char[GRID_WIDTH * GRID_HEIGHT]; - - for (int i = 0; i < GRID_WIDTH * GRID_HEIGHT; i++) { - if (rgen(rng) == 1) { - node_grid[i] = 1; - } - else { - node_grid[i] = 0; - } - } - - // ====================================== Setup Rendering ========================================================== - - unsigned char* pixel_array = new sf::Uint8[WINDOW_X * WINDOW_Y * 4]; - - for (int i = 0; i < GRID_WIDTH * GRID_HEIGHT * 4; i += 4) { - - pixel_array[i] = i % 255; // R? - pixel_array[i + 1] = 70; // G? - pixel_array[i + 2] = 100; // B? - pixel_array[i + 3] = 100; // A? - } - - GLuint texture; - - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); - - ////////////////////////// - - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_DECAL); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_DECAL); - - // when texture area is small, bilinear filter the closest mipmap - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); - // when texture area is large, bilinear filter the first mipmap - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - // texture should tile - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, GRID_WIDTH, GRID_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel_array); - - glGenerateMipmap(GL_TEXTURE_2D); - - - delete pixel_array; - - - - // ========================================= Setup the buffers ================================================== - - int err = 0; - - cl_mem frontWriteBuffer = clCreateFromGLTexture(context , CL_MEM_WRITE_ONLY, GL_TEXTURE_2D, 0, texture, &err); - cl_mem frontReadBuffer = clCreateFromGLTexture(context, CL_MEM_READ_ONLY, GL_TEXTURE_2D, 0, texture, &err); - cl_mem backBuffer = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, sizeof(int), (void*)node_grid, &err); - - cl_mem workerCountBuffer = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(int), &WORKER_SIZE, &err); - cl_mem gridWidthBuffer = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(int), &GRID_WIDTH, &err); - cl_mem gridHeightBuffer = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(int), &GRID_HEIGHT, &err); - - // Compute kernel args - status = clSetKernelArg(compute_kernel, 0, sizeof(cl_mem), (void *)&frontWriteBuffer); - status = clSetKernelArg(compute_kernel, 1, sizeof(cl_mem), (void *)&backBuffer); - status = clSetKernelArg(compute_kernel, 2, sizeof(cl_mem), (void *)&workerCountBuffer); - status = clSetKernelArg(compute_kernel, 3, sizeof(cl_mem), (void *)&gridWidthBuffer); - status = clSetKernelArg(compute_kernel, 4, sizeof(cl_mem), (void *)&gridHeightBuffer); - - status = clSetKernelArg(align_kernel, 0, sizeof(cl_mem), (void *)&frontReadBuffer); - status = clSetKernelArg(align_kernel, 1, sizeof(cl_mem), (void *)&backBuffer); - status = clSetKernelArg(align_kernel, 2, sizeof(cl_mem), (void *)&workerCountBuffer); - status = clSetKernelArg(align_kernel, 3, sizeof(cl_mem), (void *)&gridWidthBuffer); - status = clSetKernelArg(align_kernel, 4, sizeof(cl_mem), (void *)&gridHeightBuffer); - - - // ===================================== Loop ================================================================== - - while (!glfwWindowShouldClose(gl_window)) { - - glClearColor(0.2f, 0.3f, 0.3f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); - - // ======================================= OpenCL Shtuff =================================================== - - // Work size, for each y line - size_t global_work_size[1] = { WORKER_SIZE }; - - status = clEnqueueAcquireGLObjects(commandQueue, 1, &frontReadBuffer, 0, 0, 0); - status = clEnqueueAcquireGLObjects(commandQueue, 1, &frontWriteBuffer, 0, 0, 0); - - status = clEnqueueNDRangeKernel(commandQueue, compute_kernel, 1, NULL, global_work_size, NULL, 0, NULL, NULL); - status = clEnqueueNDRangeKernel(commandQueue, align_kernel, 1, NULL, global_work_size, NULL, 0, NULL, NULL); - - status = clEnqueueReleaseGLObjects(commandQueue, 1, &frontReadBuffer, 0, NULL, NULL); - status = clEnqueueReleaseGLObjects(commandQueue, 1, &frontWriteBuffer, 0, NULL, NULL); - - clFinish(commandQueue); - - // ======================================= Rendering Shtuff ================================================= - - glfwPollEvents(); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, texture); - glUniform1i(glGetUniformLocation(vert_frag_shaders.Program, "pixel_texture"), 0); - - // Draw the triangle - vert_frag_shaders.Use(); - glBindVertexArray(VAO); - glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); - glBindVertexArray(0); - - glFinish(); - - // Render - glfwSwapBuffers(gl_window); - - - - } - - glfwTerminate(); - - // Release the buffers - status = clReleaseMemObject(frontReadBuffer); - status = clReleaseMemObject(workerCountBuffer); - status = clReleaseMemObject(gridWidthBuffer); - status = clReleaseMemObject(gridHeightBuffer); - - // And the program stuff - status = clReleaseKernel(compute_kernel); - status = clReleaseProgram(compute_program); - status = clReleaseProgram(align_program); - status = clReleaseCommandQueue(commandQueue); - status = clReleaseContext(context); - - if (devices != NULL) - { - delete devices; - devices = NULL; - } - - return SUCCESS; -} \ No newline at end of file diff --git a/Conway_OpenCL/Conway_OpenCL.vcxproj b/Conway_OpenCL/Conway_OpenCL.vcxproj deleted file mode 100644 index 7498537..0000000 --- a/Conway_OpenCL/Conway_OpenCL.vcxproj +++ /dev/null @@ -1,241 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {000000DA-0000-0000-0000-000000000000} - Conway_OpenCL - Conway_OpenCL - - - - Application - true - v140 - MultiByte - - - Application - true - v140 - MultiByte - - - Application - false - v140 - false - MultiByte - - - Application - false - v140 - true - MultiByte - - - - - - - - - - - - - - - - - - - false - $(SolutionDir)bin\x86\$(Configuration)\ - temp\x86\$(Configuration)\ - Z:\Cpp_Libs\SFML-Visual_Studio2015RCx32\include;Z:\Cpp_Libs\glew-1.13.0\include;Z:\Cpp_Libs\glfw-3.1.2.bin.WIN32\include;$(IncludePath) - Z:\Cpp_Libs\SFML-Visual_Studio2015RCx32\lib;Z:\Cpp_Libs\glew-1.13.0\lib\Release\Win32;Z:\Cpp_Libs\glfw-3.1.2.bin.WIN32\lib-vc2015;$(LibraryPath) - - - $(SolutionDir)bin\x86\$(Configuration)\ - temp\x86\$(Configuration)\ - Z:\Cpp_Libs\SFML-Visual_Studio2015RCx32\include;Z:\Cpp_Libs\glew-1.13.0\include;Z:\Cpp_Libs\glfw-3.1.2.bin.WIN32\include;$(IncludePath) - Z:\Cpp_Libs\SFML-Visual_Studio2015RCx32\lib;Z:\Cpp_Libs\glew-1.13.0\lib\Release\Win32;Z:\Cpp_Libs\glfw-3.1.2.bin.WIN32\lib-vc2015;$(LibraryPath) - - - $(SolutionDir)bin\x86_64\$(Configuration)\ - temp\x86_64\$(Configuration)\ - Z:\Cpp_Libs\SFML-Visual_Studio2015RCx64\include;Z:\Cpp_Libs\glew-1.13.0\include;Z:\Cpp_Libs\glfw-3.1.2.bin.WIN64\include;$(IncludePath) - Z:\Cpp_Libs\SFML-Visual_Studio2015RCx64\lib;Z:\Cpp_Libs\glew-1.13.0\lib\Release\x64;Z:\Cpp_Libs\glfw-3.1.2.bin.WIN64\lib-vc2015;$(LibraryPath) - - - $(SolutionDir)bin\x86_64\$(Configuration)\ - temp\x86_64\$(Configuration)\ - false - Z:\Cpp_Libs\SFML-Visual_Studio2015RCx64\include;Z:\Cpp_Libs\glew-1.13.0\include;Z:\Cpp_Libs\glfw-3.1.2.bin.WIN64\include;$(IncludePath) - Z:\Cpp_Libs\SFML-Visual_Studio2015RCx64\lib;Z:\Cpp_Libs\glew-1.13.0\lib\Release\x64;Z:\Cpp_Libs\glfw-3.1.2.bin.WIN64\lib-vc2015;$(LibraryPath) - - - - Level3 - Disabled - ../../../../include;../../../../include/SDKUtil;$(AMDAPPSDKROOT)/include;Z:\Cpp_Libs\SFML-Visual_Studio2015RCx32\include;%(AdditionalIncludeDirectories) - Disabled - WIN32;_WINDOWS;_DEBUG;_CRT_SECURE_NO_WARNINGS;CMAKE_INTDIR="Debug";%(PreprocessorDefinitions) - false - true - CompileAsCpp - 4005;4996 - ProgramDatabase - $(SolutionDir)bin/x86/Debug/HelloWorld.pdb - Debug - - - true - ..\..\..\..\lib\win32\;$(AMDAPPSDKROOT)\lib\x86\;%(AdditionalLibraryDirectories) - kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib;OpenCL.lib;opengl32.lib;glew32.lib;glfw3.lib;sfml-graphics-d.lib;sfml-audio-d.lib;sfml-network-d.lib;sfml-system-d.lib;sfml-window-d.lib;%(AdditionalDependencies) - Console - false - /machine:X86 /debug %(AdditionalOptions) - $(SolutionDir)bin/x86/Debug/HelloWorld.lib - - - copy conway_compute.cl "$(OutDir)conway_kernel.cl" /Y -copy conway_align.cl "$(OutDir)conway_kernel.cl" /Y - - - - - Level3 - Disabled - ../../../../include;../../../../include/SDKUtil;$(AMDAPPSDKROOT)/include;Z:\Cpp_Libs\SFML-Visual_Studio2015RCx64\include;%(AdditionalIncludeDirectories) - Disabled - WIN32;_WINDOWS;_DEBUG;_CRT_SECURE_NO_WARNINGS;CMAKE_INTDIR="Debug";%(PreprocessorDefinitions) - true - $(SolutionDir)bin/x86_64/Debug/HelloWorld.pdb - Debug - CompileAsCpp - 4005;4996 - - - true - ..\..\..\..\lib\win64\;$(AMDAPPSDKROOT)\lib\x86_64\;%(AdditionalLibraryDirectories) - kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib;OpenCL.lib;opengl32.lib;glfw3.lib;glew32.lib;sfml-graphics-d.lib;sfml-audio-d.lib;sfml-network-d.lib;sfml-system-d.lib;sfml-window-d.lib;%(AdditionalDependencies) - Console - $(SolutionDir)bin/x86_64/Debug/HelloWorld.lib - false - /machine:x64 /debug %(AdditionalOptions) - - - copy conway_compute.cl "$(OutDir)conway_kernel.cl" /Y -copy conway_align.cl "$(OutDir)conway_kernel.cl" /Y - - - - - Level3 - MaxSpeed - - - false - ../../../../include;../../../../include/SDKUtil;$(AMDAPPSDKROOT)/include;Z:\Cpp_Libs\SFML-Visual_Studio2015RCx32\include;%(AdditionalIncludeDirectories) - - AnySuitable - WIN32;_WINDOWS;NDEBUG;_CRT_SECURE_NO_WARNINGS;CMAKE_INTDIR="Release";%(PreprocessorDefinitions) - true - $(SolutionDir)bin/x86/Release/HelloWorld.pdb - CompileAsCpp - 4005;4996 - Release - - - false - - - - - kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib;OpenCL.lib;opengl32.lib;glew32.lib;glfw3.lib;sfml-graphics.lib;sfml-audio.lib;sfml-network.lib;sfml-system.lib;sfml-window.lib;%(AdditionalDependencies) - ..\..\..\..\lib\win32\;$(AMDAPPSDKROOT)\lib\x86\;%(AdditionalLibraryDirectories) - Console - $(SolutionDir)bin/x86/Release/HelloWorld.lib - false - /machine:X86 %(AdditionalOptions) - - - false - - - copy conway_compute.cl "$(OutDir)conway_kernel.cl" /Y -copy conway_align.cl "$(OutDir)conway_kernel.cl" /Y - - - - - Level3 - MaxSpeed - - - false - ../../../../include;../../../../include/SDKUtil;$(AMDAPPSDKROOT)/include;Z:\Cpp_Libs\SFML-Visual_Studio2015RCx64\include;%(AdditionalIncludeDirectories) - AnySuitable - - WIN32;_WINDOWS;NDEBUG;_CRT_SECURE_NO_WARNINGS;CMAKE_INTDIR="Release";%(PreprocessorDefinitions) - true - Release - CompileAsCpp - 4005;4996 - $(SolutionDir)bin/x86_64/Release/HelloWorld.pdb - false - - - false - - - - - ..\..\..\..\lib\win64\;$(AMDAPPSDKROOT)\lib\x86_64\;%(AdditionalLibraryDirectories) - kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib;OpenCL.lib;opengl32.lib;glfw3.lib;glew32.lib;sfml-graphics.lib;sfml-audio.lib;sfml-network.lib;sfml-system.lib;sfml-window.lib;%(AdditionalDependencies) - Console - - $(SolutionDir)bin/x86_64/Release/HelloWorld.lib - false - /machine:x64 %(AdditionalOptions) - - - copy conway_compute.cl "$(OutDir)conway_kernel.cl" /Y -copy conway_align.cl "$(OutDir)conway_kernel.cl" /Y - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Conway_OpenCL/Shader.hpp b/Conway_OpenCL/Shader.hpp deleted file mode 100644 index d9562a1..0000000 --- a/Conway_OpenCL/Shader.hpp +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef SHADER_H -#define SHADER_H - -#include -#include -#include -#include - -#include - -class Shader { -public: - GLuint Program; - // Constructor generates the shader on the fly - Shader(const GLchar* vertexPath, const GLchar* fragmentPath) { - // 1. Retrieve the vertex/fragment source code from filePath - std::string vertexCode; - std::string fragmentCode; - std::ifstream vShaderFile; - std::ifstream fShaderFile; - // ensures ifstream objects can throw exceptions: - vShaderFile.exceptions(std::ifstream::badbit); - fShaderFile.exceptions(std::ifstream::badbit); - try { - // Open files - vShaderFile.open(vertexPath); - fShaderFile.open(fragmentPath); - std::stringstream vShaderStream, fShaderStream; - // Read file's buffer contents into streams - vShaderStream << vShaderFile.rdbuf(); - fShaderStream << fShaderFile.rdbuf(); - // close file handlers - vShaderFile.close(); - fShaderFile.close(); - // Convert stream into string - vertexCode = vShaderStream.str(); - fragmentCode = fShaderStream.str(); - } - catch (std::ifstream::failure e) { - std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl; - } - const GLchar* vShaderCode = vertexCode.c_str(); - const GLchar * fShaderCode = fragmentCode.c_str(); - - GLint success = 0; - GLchar infoLog[512]; - - // Vertex Shader - GLuint vertex = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(vertex, 1, &vShaderCode, NULL); - glCompileShader(vertex); - // Print compile errors if any - glGetShaderiv(vertex, GL_COMPILE_STATUS, &success); - if (!success) { - glGetShaderInfoLog(vertex, 512, NULL, infoLog); - std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl; - } - // Fragment Shader - GLuint fragment = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(fragment, 1, &fShaderCode, NULL); - glCompileShader(fragment); - // Print compile errors if any - glGetShaderiv(fragment, GL_COMPILE_STATUS, &success); - if (!success) { - glGetShaderInfoLog(fragment, 512, NULL, infoLog); - std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl; - } - // Shader Program - this->Program = glCreateProgram(); - glAttachShader(this->Program, vertex); - glAttachShader(this->Program, fragment); - glLinkProgram(this->Program); - // Print linking errors if any - glGetProgramiv(this->Program, GL_LINK_STATUS, &success); - if (!success) { - glGetProgramInfoLog(this->Program, 512, NULL, infoLog); - std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; - } - // Delete the shaders as they're linked into our program now and no longer necessery - glDeleteShader(vertex); - glDeleteShader(fragment); - - } - // Uses the current shader - void Use() { - glUseProgram(this->Program); - } -}; - -#endif \ No newline at end of file diff --git a/Conway_OpenCL/conway_align.cl b/Conway_OpenCL/conway_align.cl deleted file mode 100644 index 195c878..0000000 --- a/Conway_OpenCL/conway_align.cl +++ /dev/null @@ -1,20 +0,0 @@ -__kernel void conway_align(__read_only image2d_t front_image, __global char* back_image, __global int* num_workers, __global int* grid_width, __global int *grid_height) -{ - const sampler_t sampler=CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST; - - // Caclulate the start and end range that this worker will be calculating - int data_length = *grid_width * *grid_height; - - int start_range = (data_length / *num_workers) * get_global_id(0); - int end_range = (data_length / *num_workers) * (get_global_id(0) + 1); - - - for (int i = start_range; i < end_range; i++){ - - uint4 pixel; - pixel = read_imageui(front_image, sampler, (int2)(i,get_global_id(0))); - - back_image[i] = pixel.w / 255; - } - -} \ No newline at end of file diff --git a/Conway_OpenCL/conway_compute.cl b/Conway_OpenCL/conway_compute.cl deleted file mode 100644 index b6d2294..0000000 --- a/Conway_OpenCL/conway_compute.cl +++ /dev/null @@ -1,59 +0,0 @@ -__kernel void conway_compute(__write_only image2d_t front_image, __global char* back_image, __global int* num_workers, __global int* grid_width, __global int *grid_height) -{ - - float4 black = (float4)(.49, .68, .81, 1); - float4 white = (float4)(.49, .68, .71, .3); - - // Caclulate the start and end range that this worker will be calculating - int data_length = *grid_width * *grid_height; - - int start_range = (data_length / *num_workers) * get_global_id(0); - int end_range = (data_length / *num_workers) * (get_global_id(0) + 1); - - // x, y + 1 - - int neighbors = 0; - - for (int i = start_range; i < end_range; i++){ - - int2 pixelcoord = (int2) (i % *grid_width, i / *grid_height); - - // add all 8 blocks to neghbors - neighbors = 0; - // Top - neighbors += back_image[i - *grid_width]; - - // Top right - neighbors += back_image[i - *grid_width + 1]; - - // Right - neighbors += back_image[i + 1]; - - // Bottom Right - neighbors += back_image[i + *grid_width + 1]; - - // Bottom - neighbors += back_image[i + *grid_width]; - - // Bottom Left - neighbors += back_image[i + *grid_width - 1]; - - // Left - neighbors += back_image[i - 1]; - - // Top left - neighbors += back_image[i - *grid_width - 1]; - - // push living status to the padded second char - - - write_imagef(front_image, pixelcoord, black); - - if (neighbors == 3 || (neighbors == 2 && back_image[i])){ - write_imagef(front_image, pixelcoord, white); - } - - //else - //write_imagei(front_image, pixelcoord, white); - } -} \ No newline at end of file diff --git a/Conway_OpenCL/fragment_shader.sh b/Conway_OpenCL/fragment_shader.sh deleted file mode 100644 index 2448770..0000000 --- a/Conway_OpenCL/fragment_shader.sh +++ /dev/null @@ -1,15 +0,0 @@ -#version 330 core -in vec3 ourColor; -in vec2 TexCoord; - -out vec4 color; - -// Texture samplers -uniform sampler2D pixel_texture; - -void main() -{ - // Linearly interpolate between both textures (second texture is only slightly combined) - //color = vec4(1.0f, 0.5f, 0.2f, 1.0f); - color = texture(pixel_texture, TexCoord); -} \ No newline at end of file diff --git a/Conway_OpenCL/vertex_shader.sh b/Conway_OpenCL/vertex_shader.sh deleted file mode 100644 index 366cf08..0000000 --- a/Conway_OpenCL/vertex_shader.sh +++ /dev/null @@ -1,16 +0,0 @@ -#version 330 core -layout (location = 0) in vec3 position; -layout (location = 1) in vec3 color; -layout (location = 2) in vec2 texCoord; - -out vec3 ourColor; -out vec2 TexCoord; - -void main() -{ - gl_Position = vec4(position, 1.0f); - ourColor = color; - // We swap the y-axis by substracing our coordinates from 1. This is done because most images have the top y-axis inversed with OpenGL's top y-axis. - // TexCoord = texCoord; - TexCoord = vec2(texCoord.x, 1.0 - texCoord.y); -} \ No newline at end of file diff --git a/Conway_OpenCL/~AutoRecover.Conway_OpenCL.vcxproj b/Conway_OpenCL/~AutoRecover.Conway_OpenCL.vcxproj deleted file mode 100644 index 7498537..0000000 --- a/Conway_OpenCL/~AutoRecover.Conway_OpenCL.vcxproj +++ /dev/null @@ -1,241 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {000000DA-0000-0000-0000-000000000000} - Conway_OpenCL - Conway_OpenCL - - - - Application - true - v140 - MultiByte - - - Application - true - v140 - MultiByte - - - Application - false - v140 - false - MultiByte - - - Application - false - v140 - true - MultiByte - - - - - - - - - - - - - - - - - - - false - $(SolutionDir)bin\x86\$(Configuration)\ - temp\x86\$(Configuration)\ - Z:\Cpp_Libs\SFML-Visual_Studio2015RCx32\include;Z:\Cpp_Libs\glew-1.13.0\include;Z:\Cpp_Libs\glfw-3.1.2.bin.WIN32\include;$(IncludePath) - Z:\Cpp_Libs\SFML-Visual_Studio2015RCx32\lib;Z:\Cpp_Libs\glew-1.13.0\lib\Release\Win32;Z:\Cpp_Libs\glfw-3.1.2.bin.WIN32\lib-vc2015;$(LibraryPath) - - - $(SolutionDir)bin\x86\$(Configuration)\ - temp\x86\$(Configuration)\ - Z:\Cpp_Libs\SFML-Visual_Studio2015RCx32\include;Z:\Cpp_Libs\glew-1.13.0\include;Z:\Cpp_Libs\glfw-3.1.2.bin.WIN32\include;$(IncludePath) - Z:\Cpp_Libs\SFML-Visual_Studio2015RCx32\lib;Z:\Cpp_Libs\glew-1.13.0\lib\Release\Win32;Z:\Cpp_Libs\glfw-3.1.2.bin.WIN32\lib-vc2015;$(LibraryPath) - - - $(SolutionDir)bin\x86_64\$(Configuration)\ - temp\x86_64\$(Configuration)\ - Z:\Cpp_Libs\SFML-Visual_Studio2015RCx64\include;Z:\Cpp_Libs\glew-1.13.0\include;Z:\Cpp_Libs\glfw-3.1.2.bin.WIN64\include;$(IncludePath) - Z:\Cpp_Libs\SFML-Visual_Studio2015RCx64\lib;Z:\Cpp_Libs\glew-1.13.0\lib\Release\x64;Z:\Cpp_Libs\glfw-3.1.2.bin.WIN64\lib-vc2015;$(LibraryPath) - - - $(SolutionDir)bin\x86_64\$(Configuration)\ - temp\x86_64\$(Configuration)\ - false - Z:\Cpp_Libs\SFML-Visual_Studio2015RCx64\include;Z:\Cpp_Libs\glew-1.13.0\include;Z:\Cpp_Libs\glfw-3.1.2.bin.WIN64\include;$(IncludePath) - Z:\Cpp_Libs\SFML-Visual_Studio2015RCx64\lib;Z:\Cpp_Libs\glew-1.13.0\lib\Release\x64;Z:\Cpp_Libs\glfw-3.1.2.bin.WIN64\lib-vc2015;$(LibraryPath) - - - - Level3 - Disabled - ../../../../include;../../../../include/SDKUtil;$(AMDAPPSDKROOT)/include;Z:\Cpp_Libs\SFML-Visual_Studio2015RCx32\include;%(AdditionalIncludeDirectories) - Disabled - WIN32;_WINDOWS;_DEBUG;_CRT_SECURE_NO_WARNINGS;CMAKE_INTDIR="Debug";%(PreprocessorDefinitions) - false - true - CompileAsCpp - 4005;4996 - ProgramDatabase - $(SolutionDir)bin/x86/Debug/HelloWorld.pdb - Debug - - - true - ..\..\..\..\lib\win32\;$(AMDAPPSDKROOT)\lib\x86\;%(AdditionalLibraryDirectories) - kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib;OpenCL.lib;opengl32.lib;glew32.lib;glfw3.lib;sfml-graphics-d.lib;sfml-audio-d.lib;sfml-network-d.lib;sfml-system-d.lib;sfml-window-d.lib;%(AdditionalDependencies) - Console - false - /machine:X86 /debug %(AdditionalOptions) - $(SolutionDir)bin/x86/Debug/HelloWorld.lib - - - copy conway_compute.cl "$(OutDir)conway_kernel.cl" /Y -copy conway_align.cl "$(OutDir)conway_kernel.cl" /Y - - - - - Level3 - Disabled - ../../../../include;../../../../include/SDKUtil;$(AMDAPPSDKROOT)/include;Z:\Cpp_Libs\SFML-Visual_Studio2015RCx64\include;%(AdditionalIncludeDirectories) - Disabled - WIN32;_WINDOWS;_DEBUG;_CRT_SECURE_NO_WARNINGS;CMAKE_INTDIR="Debug";%(PreprocessorDefinitions) - true - $(SolutionDir)bin/x86_64/Debug/HelloWorld.pdb - Debug - CompileAsCpp - 4005;4996 - - - true - ..\..\..\..\lib\win64\;$(AMDAPPSDKROOT)\lib\x86_64\;%(AdditionalLibraryDirectories) - kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib;OpenCL.lib;opengl32.lib;glfw3.lib;glew32.lib;sfml-graphics-d.lib;sfml-audio-d.lib;sfml-network-d.lib;sfml-system-d.lib;sfml-window-d.lib;%(AdditionalDependencies) - Console - $(SolutionDir)bin/x86_64/Debug/HelloWorld.lib - false - /machine:x64 /debug %(AdditionalOptions) - - - copy conway_compute.cl "$(OutDir)conway_kernel.cl" /Y -copy conway_align.cl "$(OutDir)conway_kernel.cl" /Y - - - - - Level3 - MaxSpeed - - - false - ../../../../include;../../../../include/SDKUtil;$(AMDAPPSDKROOT)/include;Z:\Cpp_Libs\SFML-Visual_Studio2015RCx32\include;%(AdditionalIncludeDirectories) - - AnySuitable - WIN32;_WINDOWS;NDEBUG;_CRT_SECURE_NO_WARNINGS;CMAKE_INTDIR="Release";%(PreprocessorDefinitions) - true - $(SolutionDir)bin/x86/Release/HelloWorld.pdb - CompileAsCpp - 4005;4996 - Release - - - false - - - - - kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib;OpenCL.lib;opengl32.lib;glew32.lib;glfw3.lib;sfml-graphics.lib;sfml-audio.lib;sfml-network.lib;sfml-system.lib;sfml-window.lib;%(AdditionalDependencies) - ..\..\..\..\lib\win32\;$(AMDAPPSDKROOT)\lib\x86\;%(AdditionalLibraryDirectories) - Console - $(SolutionDir)bin/x86/Release/HelloWorld.lib - false - /machine:X86 %(AdditionalOptions) - - - false - - - copy conway_compute.cl "$(OutDir)conway_kernel.cl" /Y -copy conway_align.cl "$(OutDir)conway_kernel.cl" /Y - - - - - Level3 - MaxSpeed - - - false - ../../../../include;../../../../include/SDKUtil;$(AMDAPPSDKROOT)/include;Z:\Cpp_Libs\SFML-Visual_Studio2015RCx64\include;%(AdditionalIncludeDirectories) - AnySuitable - - WIN32;_WINDOWS;NDEBUG;_CRT_SECURE_NO_WARNINGS;CMAKE_INTDIR="Release";%(PreprocessorDefinitions) - true - Release - CompileAsCpp - 4005;4996 - $(SolutionDir)bin/x86_64/Release/HelloWorld.pdb - false - - - false - - - - - ..\..\..\..\lib\win64\;$(AMDAPPSDKROOT)\lib\x86_64\;%(AdditionalLibraryDirectories) - kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib;OpenCL.lib;opengl32.lib;glfw3.lib;glew32.lib;sfml-graphics.lib;sfml-audio.lib;sfml-network.lib;sfml-system.lib;sfml-window.lib;%(AdditionalDependencies) - Console - - $(SolutionDir)bin/x86_64/Release/HelloWorld.lib - false - /machine:x64 %(AdditionalOptions) - - - copy conway_compute.cl "$(OutDir)conway_kernel.cl" /Y -copy conway_align.cl "$(OutDir)conway_kernel.cl" /Y - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/FindSFML.cmake b/FindSFML.cmake new file mode 100644 index 0000000..9acf23d --- /dev/null +++ b/FindSFML.cmake @@ -0,0 +1,369 @@ +# This script locates the SFML library +# ------------------------------------ +# +# Usage +# ----- +# +# When you try to locate the SFML libraries, you must specify which modules you want to use (system, window, graphics, network, audio, main). +# If none is given, the SFML_LIBRARIES variable will be empty and you'll end up linking to nothing. +# example: +# find_package(SFML COMPONENTS graphics window system) # find the graphics, window and system modules +# +# You can enforce a specific version, either MAJOR.MINOR or only MAJOR. +# If nothing is specified, the version won't be checked (i.e. any version will be accepted). +# example: +# find_package(SFML COMPONENTS ...) # no specific version required +# find_package(SFML 2 COMPONENTS ...) # any 2.x version +# find_package(SFML 2.4 COMPONENTS ...) # version 2.4 or greater +# +# By default, the dynamic libraries of SFML will be found. To find the static ones instead, +# you must set the SFML_STATIC_LIBRARIES variable to TRUE before calling find_package(SFML ...). +# Since you have to link yourself all the SFML dependencies when you link it statically, the following +# additional variables are defined: SFML_XXX_DEPENDENCIES and SFML_DEPENDENCIES (see their detailed +# description below). +# In case of static linking, the SFML_STATIC macro will also be defined by this script. +# example: +# set(SFML_STATIC_LIBRARIES TRUE) +# find_package(SFML 2 COMPONENTS network system) +# +# On Mac OS X if SFML_STATIC_LIBRARIES is not set to TRUE then by default CMake will search for frameworks unless +# CMAKE_FIND_FRAMEWORK is set to "NEVER" for example. Please refer to CMake documentation for more details. +# Moreover, keep in mind that SFML frameworks are only available as release libraries unlike dylibs which +# are available for both release and debug modes. +# +# If SFML is not installed in a standard path, you can use the SFML_ROOT CMake (or environment) variable +# to tell CMake where SFML is. +# +# Output +# ------ +# +# This script defines the following variables: +# - For each specified module XXX (system, window, graphics, network, audio, main): +# - SFML_XXX_LIBRARY_DEBUG: the name of the debug library of the xxx module (set to SFML_XXX_LIBRARY_RELEASE is no debug version is found) +# - SFML_XXX_LIBRARY_RELEASE: the name of the release library of the xxx module (set to SFML_XXX_LIBRARY_DEBUG is no release version is found) +# - SFML_XXX_LIBRARY: the name of the library to link to for the xxx module (includes both debug and optimized names if necessary) +# - SFML_XXX_FOUND: true if either the debug or release library of the xxx module is found +# - SFML_XXX_DEPENDENCIES: the list of libraries the module depends on, in case of static linking +# - SFML_LIBRARIES: the list of all libraries corresponding to the required modules +# - SFML_FOUND: true if all the required modules are found +# - SFML_INCLUDE_DIR: the path where SFML headers are located (the directory containing the SFML/Config.hpp file) +# - SFML_DEPENDENCIES: the list of libraries SFML depends on, in case of static linking +# +# example: +# find_package(SFML 2 COMPONENTS system window graphics audio REQUIRED) +# include_directories(${SFML_INCLUDE_DIR}) +# add_executable(myapp ...) +# target_link_libraries(myapp ${SFML_LIBRARIES}) + +# define the SFML_STATIC macro if static build was chosen +if(SFML_STATIC_LIBRARIES) + add_definitions(-DSFML_STATIC) +endif() + +# define the list of search paths for headers and libraries +set(FIND_SFML_PATHS + ${SFML_ROOT} + $ENV{SFML_ROOT} + ~/Library/Frameworks + /Library/Frameworks + /usr/local + /usr + /sw + /opt/local + /opt/csw + /opt) + +# find the SFML include directory +find_path(SFML_INCLUDE_DIR SFML/Config.hpp + PATH_SUFFIXES include + PATHS ${FIND_SFML_PATHS}) + +# check the version number +set(SFML_VERSION_OK TRUE) +if(SFML_FIND_VERSION AND SFML_INCLUDE_DIR) + # extract the major and minor version numbers from SFML/Config.hpp + # we have to handle framework a little bit differently: + if("${SFML_INCLUDE_DIR}" MATCHES "SFML.framework") + set(SFML_CONFIG_HPP_INPUT "${SFML_INCLUDE_DIR}/Headers/Config.hpp") + else() + set(SFML_CONFIG_HPP_INPUT "${SFML_INCLUDE_DIR}/SFML/Config.hpp") + endif() + FILE(READ "${SFML_CONFIG_HPP_INPUT}" SFML_CONFIG_HPP_CONTENTS) + STRING(REGEX REPLACE ".*#define SFML_VERSION_MAJOR ([0-9]+).*" "\\1" SFML_VERSION_MAJOR "${SFML_CONFIG_HPP_CONTENTS}") + STRING(REGEX REPLACE ".*#define SFML_VERSION_MINOR ([0-9]+).*" "\\1" SFML_VERSION_MINOR "${SFML_CONFIG_HPP_CONTENTS}") + STRING(REGEX REPLACE ".*#define SFML_VERSION_PATCH ([0-9]+).*" "\\1" SFML_VERSION_PATCH "${SFML_CONFIG_HPP_CONTENTS}") + if (NOT "${SFML_VERSION_PATCH}" MATCHES "^[0-9]+$") + set(SFML_VERSION_PATCH 0) + endif() + math(EXPR SFML_REQUESTED_VERSION "${SFML_FIND_VERSION_MAJOR} * 10000 + ${SFML_FIND_VERSION_MINOR} * 100 + ${SFML_FIND_VERSION_PATCH}") + + # if we could extract them, compare with the requested version number + if (SFML_VERSION_MAJOR) + # transform version numbers to an integer + math(EXPR SFML_VERSION "${SFML_VERSION_MAJOR} * 10000 + ${SFML_VERSION_MINOR} * 100 + ${SFML_VERSION_PATCH}") + + # compare them + if(SFML_VERSION LESS SFML_REQUESTED_VERSION) + set(SFML_VERSION_OK FALSE) + endif() + else() + # SFML version is < 2.0 + if (SFML_REQUESTED_VERSION GREATER 10900) + set(SFML_VERSION_OK FALSE) + set(SFML_VERSION_MAJOR 1) + set(SFML_VERSION_MINOR x) + set(SFML_VERSION_PATCH x) + endif() + endif() +endif() + +# find the requested modules +set(SFML_FOUND TRUE) # will be set to false if one of the required modules is not found +foreach(FIND_SFML_COMPONENT ${SFML_FIND_COMPONENTS}) + string(TOLOWER ${FIND_SFML_COMPONENT} FIND_SFML_COMPONENT_LOWER) + string(TOUPPER ${FIND_SFML_COMPONENT} FIND_SFML_COMPONENT_UPPER) + set(FIND_SFML_COMPONENT_NAME sfml-${FIND_SFML_COMPONENT_LOWER}) + + # no suffix for sfml-main, it is always a static library + if(FIND_SFML_COMPONENT_LOWER STREQUAL "main") + # release library + find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE + NAMES ${FIND_SFML_COMPONENT_NAME} + PATH_SUFFIXES lib64 lib + PATHS ${FIND_SFML_PATHS}) + + # debug library + find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG + NAMES ${FIND_SFML_COMPONENT_NAME}-d + PATH_SUFFIXES lib64 lib + PATHS ${FIND_SFML_PATHS}) + else() + # static release library + find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_RELEASE + NAMES ${FIND_SFML_COMPONENT_NAME}-s + PATH_SUFFIXES lib64 lib + PATHS ${FIND_SFML_PATHS}) + + # static debug library + find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_DEBUG + NAMES ${FIND_SFML_COMPONENT_NAME}-s-d + PATH_SUFFIXES lib64 lib + PATHS ${FIND_SFML_PATHS}) + + # dynamic release library + find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_RELEASE + NAMES ${FIND_SFML_COMPONENT_NAME} + PATH_SUFFIXES lib64 lib + PATHS ${FIND_SFML_PATHS}) + + # dynamic debug library + find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_DEBUG + NAMES ${FIND_SFML_COMPONENT_NAME}-d + PATH_SUFFIXES lib64 lib + PATHS ${FIND_SFML_PATHS}) + + # choose the entries that fit the requested link type + if(SFML_STATIC_LIBRARIES) + if(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_RELEASE) + set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_RELEASE}) + endif() + if(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_DEBUG) + set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_DEBUG}) + endif() + else() + if(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_RELEASE) + set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_RELEASE}) + endif() + if(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_DEBUG) + set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_DEBUG}) + endif() + endif() + endif() + + if (SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG OR SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE) + # library found + set(SFML_${FIND_SFML_COMPONENT_UPPER}_FOUND TRUE) + + # if both are found, set SFML_XXX_LIBRARY to contain both + if (SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG AND SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE) + set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY debug ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG} + optimized ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE}) + endif() + + # if only one debug/release variant is found, set the other to be equal to the found one + if (SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG AND NOT SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE) + # debug and not release + set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG}) + set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG}) + endif() + if (SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE AND NOT SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG) + # release and not debug + set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE}) + set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE}) + endif() + else() + # library not found + set(SFML_FOUND FALSE) + set(SFML_${FIND_SFML_COMPONENT_UPPER}_FOUND FALSE) + set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY "") + set(FIND_SFML_MISSING "${FIND_SFML_MISSING} SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY") + endif() + + # mark as advanced + MARK_AS_ADVANCED(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY + SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE + SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG + SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_RELEASE + SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_DEBUG + SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_RELEASE + SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_DEBUG) + + # add to the global list of libraries + set(SFML_LIBRARIES ${SFML_LIBRARIES} "${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY}") +endforeach() + +# in case of static linking, we must also define the list of all the dependencies of SFML libraries +if(SFML_STATIC_LIBRARIES) + + # detect the OS + if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") + set(FIND_SFML_OS_WINDOWS 1) + elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") + set(FIND_SFML_OS_LINUX 1) + elseif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") + set(FIND_SFML_OS_FREEBSD 1) + elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + set(FIND_SFML_OS_MACOSX 1) + endif() + + # start with an empty list + set(SFML_DEPENDENCIES) + set(FIND_SFML_DEPENDENCIES_NOTFOUND) + + # macro that searches for a 3rd-party library + macro(find_sfml_dependency output friendlyname) + # No lookup in environment variables (PATH on Windows), as they may contain wrong library versions + find_library(${output} NAMES ${ARGN} PATHS ${FIND_SFML_PATHS} PATH_SUFFIXES lib NO_SYSTEM_ENVIRONMENT_PATH) + if(${${output}} STREQUAL "${output}-NOTFOUND") + unset(output) + set(FIND_SFML_DEPENDENCIES_NOTFOUND "${FIND_SFML_DEPENDENCIES_NOTFOUND} ${friendlyname}") + endif() + endmacro() + + # sfml-system + list(FIND SFML_FIND_COMPONENTS "system" FIND_SFML_SYSTEM_COMPONENT) + if(NOT ${FIND_SFML_SYSTEM_COMPONENT} EQUAL -1) + + # update the list -- these are only system libraries, no need to find them + if(FIND_SFML_OS_LINUX OR FIND_SFML_OS_FREEBSD OR FIND_SFML_OS_MACOSX) + set(SFML_SYSTEM_DEPENDENCIES "pthread") + endif() + if(FIND_SFML_OS_LINUX) + set(SFML_SYSTEM_DEPENDENCIES ${SFML_SYSTEM_DEPENDENCIES} "rt") + endif() + if(FIND_SFML_OS_WINDOWS) + set(SFML_SYSTEM_DEPENDENCIES "winmm") + endif() + set(SFML_DEPENDENCIES ${SFML_SYSTEM_DEPENDENCIES} ${SFML_DEPENDENCIES}) + endif() + + # sfml-network + list(FIND SFML_FIND_COMPONENTS "network" FIND_SFML_NETWORK_COMPONENT) + if(NOT ${FIND_SFML_NETWORK_COMPONENT} EQUAL -1) + + # update the list -- these are only system libraries, no need to find them + if(FIND_SFML_OS_WINDOWS) + set(SFML_NETWORK_DEPENDENCIES "ws2_32") + endif() + set(SFML_DEPENDENCIES ${SFML_NETWORK_DEPENDENCIES} ${SFML_DEPENDENCIES}) + endif() + + # sfml-window + list(FIND SFML_FIND_COMPONENTS "window" FIND_SFML_WINDOW_COMPONENT) + if(NOT ${FIND_SFML_WINDOW_COMPONENT} EQUAL -1) + + # find libraries + if(FIND_SFML_OS_LINUX OR FIND_SFML_OS_FREEBSD) + find_sfml_dependency(X11_LIBRARY "X11" X11) + find_sfml_dependency(LIBXCB_LIBRARIES "XCB" xcb libxcb) + find_sfml_dependency(X11_XCB_LIBRARY "X11-xcb" X11-xcb libX11-xcb) + find_sfml_dependency(XCB_RANDR_LIBRARY "xcb-randr" xcb-randr libxcb-randr) + find_sfml_dependency(XCB_IMAGE_LIBRARY "xcb-image" xcb-image libxcb-image) + endif() + + if(FIND_SFML_OS_LINUX) + find_sfml_dependency(UDEV_LIBRARIES "UDev" udev libudev) + endif() + + # update the list + if(FIND_SFML_OS_WINDOWS) + set(SFML_WINDOW_DEPENDENCIES ${SFML_WINDOW_DEPENDENCIES} "opengl32" "winmm" "gdi32") + elseif(FIND_SFML_OS_LINUX) + set(SFML_WINDOW_DEPENDENCIES ${SFML_WINDOW_DEPENDENCIES} "GL" ${X11_LIBRARY} ${LIBXCB_LIBRARIES} ${X11_XCB_LIBRARY} ${XCB_RANDR_LIBRARY} ${XCB_IMAGE_LIBRARY} ${UDEV_LIBRARIES}) + elseif(FIND_SFML_OS_FREEBSD) + set(SFML_WINDOW_DEPENDENCIES ${SFML_WINDOW_DEPENDENCIES} "GL" ${X11_LIBRARY} ${LIBXCB_LIBRARIES} ${X11_XCB_LIBRARY} ${XCB_RANDR_LIBRARY} ${XCB_IMAGE_LIBRARY} "usbhid") + elseif(FIND_SFML_OS_MACOSX) + set(SFML_WINDOW_DEPENDENCIES ${SFML_WINDOW_DEPENDENCIES} "-framework OpenGL -framework Foundation -framework AppKit -framework IOKit -framework Carbon") + endif() + set(SFML_DEPENDENCIES ${SFML_WINDOW_DEPENDENCIES} ${SFML_DEPENDENCIES}) + endif() + + # sfml-graphics + list(FIND SFML_FIND_COMPONENTS "graphics" FIND_SFML_GRAPHICS_COMPONENT) + if(NOT ${FIND_SFML_GRAPHICS_COMPONENT} EQUAL -1) + + # find libraries + find_sfml_dependency(FREETYPE_LIBRARY "FreeType" freetype) + find_sfml_dependency(JPEG_LIBRARY "libjpeg" jpeg) + + # update the list + set(SFML_GRAPHICS_DEPENDENCIES ${FREETYPE_LIBRARY} ${JPEG_LIBRARY}) + set(SFML_DEPENDENCIES ${SFML_GRAPHICS_DEPENDENCIES} ${SFML_DEPENDENCIES}) + endif() + + # sfml-audio + list(FIND SFML_FIND_COMPONENTS "audio" FIND_SFML_AUDIO_COMPONENT) + if(NOT ${FIND_SFML_AUDIO_COMPONENT} EQUAL -1) + + # find libraries + find_sfml_dependency(OPENAL_LIBRARY "OpenAL" openal openal32) + find_sfml_dependency(OGG_LIBRARY "Ogg" ogg) + find_sfml_dependency(VORBIS_LIBRARY "Vorbis" vorbis) + find_sfml_dependency(VORBISFILE_LIBRARY "VorbisFile" vorbisfile) + find_sfml_dependency(VORBISENC_LIBRARY "VorbisEnc" vorbisenc) + find_sfml_dependency(FLAC_LIBRARY "FLAC" FLAC) + + # update the list + set(SFML_AUDIO_DEPENDENCIES ${OPENAL_LIBRARY} ${FLAC_LIBRARY} ${VORBISENC_LIBRARY} ${VORBISFILE_LIBRARY} ${VORBIS_LIBRARY} ${OGG_LIBRARY}) + set(SFML_DEPENDENCIES ${SFML_DEPENDENCIES} ${SFML_AUDIO_DEPENDENCIES}) + endif() + +endif() + +# handle errors +if(NOT SFML_VERSION_OK) + # SFML version not ok + set(FIND_SFML_ERROR "SFML found but version too low (requested: ${SFML_FIND_VERSION}, found: ${SFML_VERSION_MAJOR}.${SFML_VERSION_MINOR}.${SFML_VERSION_PATCH})") + set(SFML_FOUND FALSE) +elseif(SFML_STATIC_LIBRARIES AND FIND_SFML_DEPENDENCIES_NOTFOUND) + set(FIND_SFML_ERROR "SFML found but some of its dependencies are missing (${FIND_SFML_DEPENDENCIES_NOTFOUND})") + set(SFML_FOUND FALSE) +elseif(NOT SFML_FOUND) + # include directory or library not found + set(FIND_SFML_ERROR "Could NOT find SFML (missing: ${FIND_SFML_MISSING})") +endif() +if (NOT SFML_FOUND) + if(SFML_FIND_REQUIRED) + # fatal error + message(FATAL_ERROR ${FIND_SFML_ERROR}) + elseif(NOT SFML_FIND_QUIETLY) + # error but continue + message("${FIND_SFML_ERROR}") + endif() +endif() + +# handle success +if(SFML_FOUND AND NOT SFML_FIND_QUIETLY) + message(STATUS "Found SFML ${SFML_VERSION_MAJOR}.${SFML_VERSION_MINOR}.${SFML_VERSION_PATCH} in ${SFML_INCLUDE_DIR}") +endif() + diff --git a/README.md b/README.md new file mode 100644 index 0000000..867212b --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ + +##About + +A simple rework of the CPU based Conway's game of life simulation on the GPU diff --git a/assets/fonts/Arial.ttf b/assets/fonts/Arial.ttf new file mode 100644 index 0000000..ab68fb1 Binary files /dev/null and b/assets/fonts/Arial.ttf differ diff --git a/assets/fonts/Arial_Bold.ttf b/assets/fonts/Arial_Bold.ttf new file mode 100644 index 0000000..940e255 Binary files /dev/null and b/assets/fonts/Arial_Bold.ttf differ diff --git a/assets/fonts/Arial_Bold_Italic.ttf b/assets/fonts/Arial_Bold_Italic.ttf new file mode 100644 index 0000000..52fd177 Binary files /dev/null and b/assets/fonts/Arial_Bold_Italic.ttf differ diff --git a/assets/fonts/Arial_Italic.ttf b/assets/fonts/Arial_Italic.ttf new file mode 100644 index 0000000..eac8b35 Binary files /dev/null and b/assets/fonts/Arial_Italic.ttf differ diff --git a/assets/fonts/unifont.ttf b/assets/fonts/unifont.ttf new file mode 100644 index 0000000..ec875c5 Binary files /dev/null and b/assets/fonts/unifont.ttf differ diff --git a/assets/screenshot.PNG b/assets/screenshot.PNG new file mode 100644 index 0000000..4d491e2 Binary files /dev/null and b/assets/screenshot.PNG differ diff --git a/assets/sfml-icon-small.png b/assets/sfml-icon-small.png new file mode 100644 index 0000000..10aa70b Binary files /dev/null and b/assets/sfml-icon-small.png differ diff --git a/include/OpenCL.h b/include/OpenCL.h new file mode 100644 index 0000000..3975d30 --- /dev/null +++ b/include/OpenCL.h @@ -0,0 +1,149 @@ +#pragma once + +#include +#include +#include +#include +#include "Vector4.hpp" +#include +#include + +#ifdef linux +#include +#include +#include + +#elif defined _WIN32 +#define CL_USE_DEPRECATED_OPENCL_1_2_APIS +#include +#include +#include + +// Note: windows.h must be included before Gl/GL.h +#include +#include + +#elif defined TARGET_OS_MAC +#include + +#endif + + +class OpenCL { + +public: + + OpenCL(); + ~OpenCL(); + + // command queues are associated with a device and context, so for multi-gpu applications you would need + // multiple command queues + + + // CONTEXTS + // - An OpenCL context is created with one or more devices. Contexts are used by the OpenCL runtime + // for managing objects such as command - queues, memory, program and kernel objects and for executing + // kernels on one or more devices specified in the context. + // - Contexts cannot be created using more than one platform! + + bool init(); + + bool compile_kernel(std::string kernel_path, std::string kernel_name); + + // Create an image buffer from an SF texture. Access Type is the read/write specifier required by OpenCL + bool create_image_buffer_from_texture(std::string buffer_name, sf::Texture* texture, cl_int access_type); + + // Have CL create and manage the texture for the image buffer. Access Type is the read/write specifier required by OpenCL + bool create_image_buffer(std::string buffer_name, sf::Vector2i size, sf::Vector2f position, cl_int access_type); + + // Create a buffer with CL_MEM_READ_ONLY and CL_MEM_COPY_HOST_PTR + int create_buffer(std::string buffer_name, cl_uint size, void* data); + + // Create a buffer with user defined data access flags + int create_buffer(std::string buffer_name, cl_uint size, void* data, cl_mem_flags flags); + + int set_kernel_arg(std::string kernel_name, int index, std::string buffer_name); + + void run_kernel(std::string kernel_name, sf::Vector2i work_size); + + void draw(sf::RenderWindow *window); + + class device { + + public: + + #pragma pack(push, 1) + struct packed_data { + + cl_device_type device_type; + cl_uint clock_frequency; + char opencl_version[64]; + cl_uint compute_units; + char device_extensions[1024]; + char device_name[256]; + char platform_name[128]; + }; + #pragma pack(pop) + + device(cl_device_id device_id, cl_platform_id platform_id); + device(const device& d); + void print(std::ostream& stream) const; + void print_packed_data(std::ostream& stream); + + cl_device_id getDeviceId() const { return device_id; }; + cl_platform_id getPlatformId() const { return platform_id; }; + + private: + + packed_data data; + + cl_device_id device_id; + cl_platform_id platform_id; + + cl_bool is_little_endian = false; + bool cl_gl_sharing = false; + + }; + +private: + + + int error = 0; + + + // The device which we have selected according to certain criteria + cl_platform_id platform_id; + cl_device_id device_id; + + // The GL shared context and its subsiquently generated command queue + cl_context context; + cl_command_queue command_queue; + + // Maps which contain a mapping from "name" to the host side CL memory object + std::unordered_map kernel_map; + std::unordered_map buffer_map; + std::unordered_map>> image_map; + std::vector device_list; + + // Query the hardware on this machine and store the devices + bool aquire_hardware(); + + // After aquiring hardware, create a shared context using platform specific CL commands + bool create_shared_context(); + + // Command queues must be created with a valid context + bool create_command_queue(); + + + // Store a cl_mem object in the buffer map + bool store_buffer(cl_mem buffer, std::string buffer_name); + + // Using CL release the memory object and remove the KVP associated with the buffer name + bool release_buffer(std::string buffer_name); + + bool load_config(); + void save_config(); + + static bool vr_assert(int error_code, std::string function_name); + +}; diff --git a/include/Vector4.hpp b/include/Vector4.hpp new file mode 100644 index 0000000..c47e9fc --- /dev/null +++ b/include/Vector4.hpp @@ -0,0 +1,479 @@ +//////////////////////////////////////////////////////////// +// +// This is a small addition to the SFML sf::Vector templates which +// adds a sf::Vector4(f, i, u) +// +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#ifndef SFML_VECTOR4_H +#define SFML_VECTOR4_H + +namespace sf { + //////////////////////////////////////////////////////////// + /// \brief Utility template class for manipulating + /// 2-dimensional vectors + /// + //////////////////////////////////////////////////////////// + template + class Vector4 { + public: + + //////////////////////////////////////////////////////////// + /// \brief Default constructor + /// + /// Creates a Vector4(0, 0). + /// + //////////////////////////////////////////////////////////// + Vector4(); + + //////////////////////////////////////////////////////////// + /// \brief Construct the vector from its coordinates + /// + /// \param X X coordinate + /// \param Y Y coordinate + /// + //////////////////////////////////////////////////////////// + Vector4(T X, T Y, T Z, T W); + + //////////////////////////////////////////////////////////// + /// \brief Construct the vector from another type of vector + /// + /// This constructor doesn't replace the copy constructor, + /// it's called only when U != T. + /// A call to this constructor will fail to compile if U + /// is not convertible to T. + /// + /// \param vector Vector to convert + /// + //////////////////////////////////////////////////////////// + template + explicit Vector4(const Vector4& vector); + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + T x; ///< X coordinate of the vector + T y; ///< Y coordinate of the vector + T z; ///< Z coordinate of the vector + T w; ///< W coordinate of the vector + }; + + //////////////////////////////////////////////////////////// + /// \relates Vector4 + /// \brief Overload of unary operator - + /// + /// \param right Vector to negate + /// + /// \return Memberwise opposite of the vector + /// + //////////////////////////////////////////////////////////// + template + Vector4 operator -(const Vector4& right); + + //////////////////////////////////////////////////////////// + /// \relates Vector4 + /// \brief Overload of binary operator += + /// + /// This operator performs a memberwise addition of both vectors, + /// and assigns the result to \a left. + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a vector) + /// + /// \return Reference to \a left + /// + //////////////////////////////////////////////////////////// + template + Vector4& operator +=(Vector4& left, const Vector4& right); + + //////////////////////////////////////////////////////////// + /// \relates Vector4 + /// \brief Overload of binary operator -= + /// + /// This operator performs a memberwise subtraction of both vectors, + /// and assigns the result to \a left. + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a vector) + /// + /// \return Reference to \a left + /// + //////////////////////////////////////////////////////////// + template + Vector4& operator -=(Vector4& left, const Vector4& right); + + //////////////////////////////////////////////////////////// + /// \relates Vector4 + /// \brief Overload of binary operator + + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a vector) + /// + /// \return Memberwise addition of both vectors + /// + //////////////////////////////////////////////////////////// + template + Vector4 operator +(const Vector4& left, const Vector4& right); + + //////////////////////////////////////////////////////////// + /// \relates Vector4 + /// \brief Overload of binary operator - + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a vector) + /// + /// \return Memberwise subtraction of both vectors + /// + //////////////////////////////////////////////////////////// + template + Vector4 operator -(const Vector4& left, const Vector4& right); + + //////////////////////////////////////////////////////////// + /// \relates Vector4 + /// \brief Overload of binary operator * + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a scalar value) + /// + /// \return Memberwise multiplication by \a right + /// + //////////////////////////////////////////////////////////// + template + Vector4 operator *(const Vector4& left, T right); + + //////////////////////////////////////////////////////////// + /// \relates Vector4 + /// \brief Overload of binary operator * + /// + /// \param left Left operand (a scalar value) + /// \param right Right operand (a vector) + /// + /// \return Memberwise multiplication by \a left + /// + //////////////////////////////////////////////////////////// + template + Vector4 operator *(T left, const Vector4& right); + + //////////////////////////////////////////////////////////// + /// \relates Vector4 + /// \brief Overload of binary operator *= + /// + /// This operator performs a memberwise multiplication by \a right, + /// and assigns the result to \a left. + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a scalar value) + /// + /// \return Reference to \a left + /// + //////////////////////////////////////////////////////////// + template + Vector4& operator *=(Vector4& left, T right); + + //////////////////////////////////////////////////////////// + /// \relates Vector4 + /// \brief Overload of binary operator / + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a scalar value) + /// + /// \return Memberwise division by \a right + /// + //////////////////////////////////////////////////////////// + template + Vector4 operator /(const Vector4& left, T right); + + //////////////////////////////////////////////////////////// + /// \relates Vector4 + /// \brief Overload of binary operator /= + /// + /// This operator performs a memberwise division by \a right, + /// and assigns the result to \a left. + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a scalar value) + /// + /// \return Reference to \a left + /// + //////////////////////////////////////////////////////////// + template + Vector4& operator /=(Vector4& left, T right); + + //////////////////////////////////////////////////////////// + /// \relates Vector4 + /// \brief Overload of binary operator == + /// + /// This operator compares strict equality between two vectors. + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a vector) + /// + /// \return True if \a left is equal to \a right + /// + //////////////////////////////////////////////////////////// + template + bool operator ==(const Vector4& left, const Vector4& right); + + //////////////////////////////////////////////////////////// + /// \relates Vector4 + /// \brief Overload of binary operator != + /// + /// This operator compares strict difference between two vectors. + /// + /// \param left Left operand (a vector) + /// \param right Right operand (a vector) + /// + /// \return True if \a left is not equal to \a right + /// + //////////////////////////////////////////////////////////// + template + bool operator !=(const Vector4& left, const Vector4& right); + + + + //////////////////////////////////////////////////////////// + template + inline Vector4::Vector4() : + x(0), + y(0), + z(0), + w(0){ + + } + + + //////////////////////////////////////////////////////////// + template + inline Vector4::Vector4(T X, T Y, T Z, T W) : + x(X), + y(Y), + z(Z), + w(W) { + + } + + + //////////////////////////////////////////////////////////// + template + template + inline Vector4::Vector4(const Vector4& vector) : + x(static_cast(vector.x)), + y(static_cast(vector.y)), + z(static_cast(vector.z)), + w(static_cast(vector.w)) { + } + + + //////////////////////////////////////////////////////////// + template + inline Vector4 operator -(const Vector4& right) { + return Vector4( + -right.x, + -right.y, + -right.z, + -right.w + ); + } + + + //////////////////////////////////////////////////////////// + template + inline Vector4& operator +=(Vector4& left, const Vector4& right) { + left.x += right.x; + left.y += right.y; + left.z += right.z; + left.w += right.w; + + return left; + } + + + //////////////////////////////////////////////////////////// + template + inline Vector4& operator -=(Vector4& left, const Vector4& right) { + left.x -= right.x; + left.y -= right.y; + left.z -= right.z; + left.w -= right.w; + + return left; + } + + + //////////////////////////////////////////////////////////// + template + inline Vector4 operator +(const Vector4& left, const Vector4& right) { + return Vector4( + left.x + right.x, + left.y + right.y, + left.z + right.z, + left.w + right.w + ); + } + + + //////////////////////////////////////////////////////////// + template + inline Vector4 operator -(const Vector4& left, const Vector4& right) { + return Vector4( + left.x - right.x, + left.y - right.y, + left.z - right.z, + left.w - right.w + ); + } + + + //////////////////////////////////////////////////////////// + template + inline Vector4 operator *(const Vector4& left, T right) { + return Vector4( + left.x * right, + left.y * right, + left.z * right, + left.w * right + ); + } + + + //////////////////////////////////////////////////////////// + template + inline Vector4 operator *(T left, const Vector4& right) { + return Vector4( + right.x * left, + right.y * left, + right.z * left, + right.w * left + ); + } + + + //////////////////////////////////////////////////////////// + template + inline Vector4& operator *=(Vector4& left, T right) { + left.x *= right; + left.y *= right; + left.z *= right; + left.w *= right; + + return left; + } + + + //////////////////////////////////////////////////////////// + template + inline Vector4 operator /(const Vector4& left, T right) { + return Vector4( + left.x / right, + left.y / right, + left.z / right, + left.w / right + ); + } + + + //////////////////////////////////////////////////////////// + template + inline Vector4& operator /=(Vector4& left, T right) { + left.x /= right; + left.y /= right; + left.z /= right; + left.w /= right; + + return left; + } + + + //////////////////////////////////////////////////////////// + template + inline bool operator ==(const Vector4& left, const Vector4& right) { + return + (left.x == right.x) && + (left.y == right.y) && + (left.z == right.z) && + (left.w == right.w);; + } + + + //////////////////////////////////////////////////////////// + template + inline bool operator !=(const Vector4& left, const Vector4& right) { + return + (left.x != right.x) || + (left.y != right.y) || + (left.z != right.z) || + (left.w != right.w); + } + + // Define the most common types + typedef Vector4 Vector4i; + typedef Vector4 Vector4u; + typedef Vector4 Vector4f; + +} // namespace sf + + +#endif // SFML_Vector4_HPP + + + //////////////////////////////////////////////////////////// + /// \class sf::Vector4 + /// \ingroup system + /// + /// sf::Vector4 is a simple class that defines a mathematical + /// vector with two coordinates (x and y). It can be used to + /// represent anything that has two dimensions: a size, a point, + /// a velocity, etc. + /// + /// The template parameter T is the type of the coordinates. It + /// can be any type that supports arithmetic operations (+, -, /, *) + /// and comparisons (==, !=), for example int or float. + /// + /// You generally don't have to care about the templated form (sf::Vector4), + /// the most common specializations have special typedefs: + /// \li sf::Vector4 is sf::Vector4f + /// \li sf::Vector4 is sf::Vector4i + /// \li sf::Vector4 is sf::Vector4u + /// + /// The sf::Vector4 class has a small and simple interface, its x and y members + /// can be accessed directly (there are no accessors like setX(), getX()) and it + /// contains no mathematical function like dot product, cross product, length, etc. + /// + /// Usage example: + /// \code + /// sf::Vector4f v1(16.5f, 24.f); + /// v1.x = 18.2f; + /// float y = v1.y; + /// + /// sf::Vector4f v2 = v1 * 5.f; + /// sf::Vector4 + /// v3 = v1 + v2; + /// + /// bool different = (v2 != v3); + /// \endcode + /// + /// Note: for 3-dimensional vectors, see sf::Vector3. + /// + //////////////////////////////////////////////////////////// diff --git a/include/util.hpp b/include/util.hpp new file mode 100644 index 0000000..903713e --- /dev/null +++ b/include/util.hpp @@ -0,0 +1,159 @@ +#pragma once +#include +#include +#include "Vector4.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +const double PI = 3.141592653589793238463; +const float PI_F = 3.14159265358979f; + +inline sf::Vector3f SphereToCart(sf::Vector2f i) { + + auto r = sf::Vector3f( + (1 * sin(i.y) * cos(i.x)), + (1 * sin(i.y) * sin(i.x)), + (1 * cos(i.y)) + ); + return r; +}; + +inline sf::Vector3f SphereToCart(sf::Vector3f i) { + + auto r = sf::Vector3f( + (i.x * sin(i.z) * cos(i.y)), + (i.x * sin(i.z) * sin(i.y)), + (i.x * cos(i.z)) + ); + return r; +}; + + +inline sf::Vector3f CartToSphere(sf::Vector3f in) { + + auto r = sf::Vector3f( + sqrt(in.x * in.x + in.y * in.y + in.z * in.z), + atan(in.y / in.x), + atan(sqrt(in.x * in.x + in.y * in.y) / in.z) + ); + return r; +}; + +inline sf::Vector2f CartToNormalizedSphere(sf::Vector3f in) { + + auto r = sf::Vector2f( + atan2(sqrt(in.x * in.x + in.y * in.y), in.z), + atan2(in.y, in.x) + ); + + return r; +} + +inline sf::Vector3f FixOrigin(sf::Vector3f base, sf::Vector3f head) { + return head - base; +} + +inline sf::Vector3f Normalize(sf::Vector3f in) { + + float multiplier = sqrt(in.x * in.x + in.y * in.y + in.z * in.z); + auto r = sf::Vector3f( + in.x / multiplier, + in.y / multiplier, + in.z / multiplier + ); + return r; + +} + +inline float DotProduct(sf::Vector3f a, sf::Vector3f b){ + return a.x * b.x + a.y * b.y + a.z * b.z; +} + +inline float Magnitude(sf::Vector3f in){ + return sqrt(in.x * in.x + in.y * in.y + in.z * in.z); +} + +inline float AngleBetweenVectors(sf::Vector3f a, sf::Vector3f b){ + return acos(DotProduct(a, b) / (Magnitude(a) * Magnitude(b))); +} + +inline float DistanceBetweenPoints(sf::Vector3f a, sf::Vector3f b) { + return sqrt(DotProduct(a, b)); +} + +inline float DegreesToRadians(float in) { + return static_cast(in * PI / 180.0f); +} + +inline float RadiansToDegrees(float in) { + return static_cast(in * 180.0f / PI); +} + +inline std::string read_file(std::string file_name){ + std::ifstream input_file(file_name); + + if (!input_file.is_open()){ + std::cout << file_name << " could not be opened" << std::endl; + return ""; + } + + std::stringstream buf; + buf << input_file.rdbuf(); + input_file.close(); + return buf.str(); +} + +inline void PrettyPrintUINT64(uint64_t i, std::stringstream* ss) { + + *ss << "[" << std::bitset<15>(i) << "]"; + *ss << "[" << std::bitset<1>(i >> 15) << "]"; + *ss << "[" << std::bitset<8>(i >> 16) << "]"; + *ss << "[" << std::bitset<8>(i >> 24) << "]"; + *ss << "[" << std::bitset<32>(i >> 32) << "]"; + +} + +inline void PrettyPrintUINT64(uint64_t i) { + + std::cout << "[" << std::bitset<15>(i) << "]"; + std::cout << "[" << std::bitset<1>(i >> 15) << "]"; + std::cout << "[" << std::bitset<8>(i >> 16) << "]"; + std::cout << "[" << std::bitset<8>(i >> 24) << "]"; + std::cout << "[" << std::bitset<32>(i >> 32) << "]" << std::endl; + +} + +inline void DumpLog(std::stringstream* ss, std::string file_name) { + + std::ofstream log_file; + log_file.open(file_name); + + log_file << ss->str(); + + log_file.close(); + +} + +#ifdef _MSC_VER +# include +# define __builtin_popcount _mm_popcnt_u32 +# define __builtin_popcountll _mm_popcnt_u64 +#endif + +inline int count_bits(int32_t v) { + + return static_cast(__builtin_popcount(v)); +} + +inline int count_bits(int64_t v) { + + return static_cast(__builtin_popcountll(v)); +} \ No newline at end of file diff --git a/kernels/conways.cl b/kernels/conways.cl new file mode 100644 index 0000000..ccb069b --- /dev/null +++ b/kernels/conways.cl @@ -0,0 +1,141 @@ +int pixel_to_index(int2 dimensions, int2 pixel) { + + if (pixel.x >= 0 && pixel.x <= dimensions.x && + pixel.y >= 0 && pixel.x <= dimensions.y ){ + + return pixel.y * dimensions.x + pixel.x; + } + + return -1; +} + + +__kernel void conways ( + global int2* image_res, + __write_only image2d_t image, + global char* first_node_buffer, + global char* second_node_buffer, + global char* buffer_flip + ){ + + size_t x_pixel = get_global_id(0); + size_t y_pixel = get_global_id(1); + + + //printf(": %i", y_pixel); + + int2 pixel = (int2)(x_pixel, y_pixel); + + //if (pixel.x > 1800) + // printf("%i, %i", pixel.x, pixel.y); + + float4 dead = (float4)(.49, .68, .81, 1); + float4 alive = (float4)(.49, .68, .71, .3); + + // add all 8 blocks to neghbors + int neighbors = 0; + int val = 0; + + if (*buffer_flip == 0){ + + // Top + val = pixel_to_index(*image_res, (int2)(pixel.x, pixel.y+1)); + if (val >= 0) + neighbors += first_node_buffer[val]; + + // Top Right + val = pixel_to_index(*image_res, (int2)(pixel.x+1, pixel.y+1)); + if (val >= 0) + neighbors += first_node_buffer[val]; + + // Right + val = pixel_to_index(*image_res, (int2)(pixel.x+1, pixel.y)); + if (val >= 0) + neighbors += first_node_buffer[val]; + + // Bottom Right + val = pixel_to_index(*image_res, (int2)(pixel.x+1, pixel.y-1)); + if (val >= 0) + neighbors += first_node_buffer[val]; + + // Bottom + val = pixel_to_index(*image_res, (int2)(pixel.x, pixel.y-1)); + if (val >= 0) + neighbors += first_node_buffer[val]; + + // Bottom Left + val = pixel_to_index(*image_res, (int2)(pixel.x-1, pixel.y-1)); + if (val >= 0) + neighbors += first_node_buffer[val]; + + // Left + val = pixel_to_index(*image_res, (int2)(pixel.x-1, pixel.y)); + if (val >= 0) + neighbors += first_node_buffer[val]; + + // Top Left + val = pixel_to_index(*image_res, (int2)(pixel.x-1, pixel.y+1)); + if (val >= 0) + neighbors += first_node_buffer[val]; + + int base = pixel_to_index(*image_res, pixel); + if (neighbors == 3 || (neighbors == 2 && first_node_buffer[base])){ + write_imagef(image, pixel, alive); + second_node_buffer[base] = 1; + } else { + write_imagef(image, pixel, dead); + second_node_buffer[base] = 0; + } + + } else { + + // Top + val = pixel_to_index(*image_res, (int2)(pixel.x, pixel.y+1)); + if (val >= 0) + neighbors += second_node_buffer[val]; + + // Top Right + val = pixel_to_index(*image_res, (int2)(pixel.x+1, pixel.y+1)); + if (val >= 0) + neighbors += second_node_buffer[val]; + + // Right + val = pixel_to_index(*image_res, (int2)(pixel.x+1, pixel.y)); + if (val >= 0) + neighbors += second_node_buffer[val]; + + // Bottom Right + val = pixel_to_index(*image_res, (int2)(pixel.x+1, pixel.y-1)); + if (val >= 0) + neighbors += second_node_buffer[val]; + + // Bottom + val = pixel_to_index(*image_res, (int2)(pixel.x, pixel.y-1)); + if (val >= 0) + neighbors += second_node_buffer[val]; + + // Bottom Left + val = pixel_to_index(*image_res, (int2)(pixel.x-1, pixel.y-1)); + if (val >= 0) + neighbors += second_node_buffer[val]; + + // Left + val = pixel_to_index(*image_res, (int2)(pixel.x-1, pixel.y)); + if (val >= 0) + neighbors += second_node_buffer[val]; + + // Top Left + val = pixel_to_index(*image_res, (int2)(pixel.x-1, pixel.y+1)); + if (val >= 0) + neighbors += second_node_buffer[val]; + + int base = pixel_to_index(*image_res, pixel); + if (neighbors == 3 || (neighbors == 2 && second_node_buffer[base])){ + write_imagef(image, pixel, alive); + first_node_buffer[base] = 1; + } else { + write_imagef(image, pixel, dead); + first_node_buffer[base] = 0; + } + } +} diff --git a/src/OpenCL.cpp b/src/OpenCL.cpp new file mode 100644 index 0000000..1e63f03 --- /dev/null +++ b/src/OpenCL.cpp @@ -0,0 +1,737 @@ +#include +#include "util.hpp" + + +OpenCL::OpenCL() { +} + +OpenCL::~OpenCL() { +} + +void OpenCL::run_kernel(std::string kernel_name, sf::Vector2i work_size) { + + size_t global_work_size[2] = { static_cast(work_size.x), static_cast(work_size.y) }; + + cl_kernel kernel = kernel_map.at(kernel_name); + + error = clEnqueueAcquireGLObjects(command_queue, 1, &buffer_map.at("viewport_image"), 0, 0, 0); + if (vr_assert(error, "clEnqueueAcquireGLObjects")) + return; + + //error = clEnqueueTask(command_queue, kernel, 0, NULL, NULL); + error = clEnqueueNDRangeKernel( + command_queue, kernel, + 2, NULL, global_work_size, + NULL, 0, NULL, NULL); + + if (vr_assert(error, "clEnqueueNDRangeKernel")) + return; + + clFinish(command_queue); + + // What if errors out and gl objects are never released? + error = clEnqueueReleaseGLObjects(command_queue, 1, &buffer_map.at("viewport_image"), 0, NULL, NULL); + if (vr_assert(error, "clEnqueueReleaseGLObjects")) + return; + +} + +void OpenCL::draw(sf::RenderWindow *window) { + + for (auto &&i: image_map) { + window->draw(i.second.first); + } +} + +bool OpenCL::aquire_hardware() +{ + + // Get the number of platforms + cl_uint platform_count = 0; + clGetPlatformIDs(0, nullptr, &platform_count); + + if (platform_count == 0) { + std::cout << "There appears to be no OpenCL platforms on this machine" << std::endl; + return false; + } + + // Get the ID's for those platforms + std::vector plt_buf(platform_count); + + clGetPlatformIDs(platform_count, plt_buf.data(), nullptr); + if (vr_assert(error, "clGetPlatformIDs")) + return false; + + // Cycle through the platform ID's + for (unsigned int i = 0; i < platform_count; i++) { + + // And get their device count + cl_uint deviceIdCount = 0; + error = clGetDeviceIDs(plt_buf[i], CL_DEVICE_TYPE_ALL, 0, nullptr, &deviceIdCount); + if (vr_assert(error, "clGetDeviceIDs")) + return false; + + if (deviceIdCount == 0) { + std::cout << "There appears to be no devices associated with this platform" << std::endl; + + } else { + + // Get the device ids and place them in the device list + std::vector deviceIds(deviceIdCount); + + error = clGetDeviceIDs(plt_buf[i], CL_DEVICE_TYPE_ALL, deviceIdCount, deviceIds.data(), NULL); + if (vr_assert(error, "clGetDeviceIDs")) + return false; + + for (int d = 0; d < deviceIds.size(); d++) { + device_list.emplace_back(device(deviceIds[d], plt_buf.at(i))); + } + } + } + + return true; +} + +bool OpenCL::create_shared_context() { + + // Hurray for standards! + // Setup the context properties to grab the current GL context + +#ifdef linux + + cl_context_properties context_properties[] = { + CL_GL_CONTEXT_KHR, (cl_context_properties)glXGetCurrentContext(), + CL_GLX_DISPLAY_KHR, (cl_context_properties)glXGetCurrentDisplay(), + CL_CONTEXT_PLATFORM, (cl_context_properties)platform_id, + 0 + }; + +#elif defined _WIN32 + + HGLRC hGLRC = wglGetCurrentContext(); + HDC hDC = wglGetCurrentDC(); + cl_context_properties context_properties[] = { + CL_CONTEXT_PLATFORM, (cl_context_properties)platform_id, + CL_GL_CONTEXT_KHR, (cl_context_properties)hGLRC, + CL_WGL_HDC_KHR, (cl_context_properties)hDC, + 0 + }; + + +#elif defined TARGET_OS_MAC + + CGLContextObj glContext = CGLGetCurrentContext(); + CGLShareGroupObj shareGroup = CGLGetShareGroup(glContext); + cl_context_properties context_properties[] = { + CL_CONTEXT_PROPERTY_USE_CGL_SHAREGROUP_APPLE, + (cl_context_properties)shareGroup, + 0 + }; + +#elif + + std::cout << "Target machine not supported for cl_khr_gl_sharing" << std::endl; + return false; + +#endif + + // Create our shared context + context = clCreateContext( + context_properties, + 1, + &device_id, + nullptr, nullptr, + &error + ); + + if (vr_assert(error, "clCreateContext")) + return false; + + return true; + +} + +bool OpenCL::create_command_queue() { + + // Command queue requires a context and device id. It can also be a device ID list + // as long as the devices reside on the same platform + if (context && device_id) { + + command_queue = clCreateCommandQueue(context, device_id, 0, &error); + if (vr_assert(error, "clCreateCommandQueue")) + return false; + + } else { + + std::cout << "Failed creating the command queue. Context or device_id not initialized" << std::endl; + return false; + } + + return true; +} + +bool OpenCL::compile_kernel(std::string kernel_path, std::string kernel_name) { + + const char* source; + std::string tmp; + + //Load in the kernel, and c stringify it + tmp = read_file(kernel_path); + source = tmp.c_str(); + + + size_t kernel_source_size = strlen(source); + + // Load the source into CL's data structure + + cl_program program = clCreateProgramWithSource( + context, 1, + &source, + &kernel_source_size, &error + ); + + // This is not for compilation, it only loads the source + if (vr_assert(error, "clCreateProgramWithSource")) + return false; + + + // Try and build the program + // "-cl-finite-math-only -cl-fast-relaxed-math -cl-unsafe-math-optimizations" + error = clBuildProgram(program, 1, &device_id, "-cl-finite-math-only -cl-fast-relaxed-math -cl-unsafe-math-optimizations", NULL, NULL); + + // Check to see if it errored out + if (vr_assert(error, "clBuildProgram")) { + + // Get the size of the queued log + size_t log_size; + clGetProgramBuildInfo(program, device_id, CL_PROGRAM_BUILD_LOG, 0, NULL, &log_size); + char *log = new char[log_size]; + + // Grab the log + clGetProgramBuildInfo(program, device_id, CL_PROGRAM_BUILD_LOG, log_size, log, NULL); + + std::cout << log; + return false; + } + + // Done initializing the kernel + cl_kernel kernel = clCreateKernel(program, kernel_name.c_str(), &error); + + if (vr_assert(error, "clCreateKernel")) + return false; + + // Do I want these to overlap when repeated?? + kernel_map[kernel_name] = kernel; + + return true; +} + +bool OpenCL::create_image_buffer_from_texture(std::string buffer_name, sf::Texture* texture, cl_int access_type) { + + if (buffer_map.count(buffer_name) > 0) { + release_buffer(buffer_name); + + // Need to check to see if we are taking care of the texture as well + if (image_map.count(buffer_name) > 0) + image_map.erase(buffer_name); + } + + cl_mem buff = clCreateFromGLTexture( + context, access_type, GL_TEXTURE_2D, + 0, texture->getNativeHandle(), &error); + + if (vr_assert(error, "clCreateFromGLTexture")) + return false; + + store_buffer(buff, buffer_name); + + return true; +} + + +bool OpenCL::create_image_buffer(std::string buffer_name, sf::Vector2i size, sf::Vector2f position, cl_int access_type) { + + if (buffer_map.count(buffer_name) > 0) { + release_buffer(buffer_name); + + // Need to check to see if we are taking care of the texture as well + if (image_map.count(buffer_name) > 0) + image_map.erase(buffer_name); + } + + std::unique_ptr texture(new sf::Texture); + texture->create(size.x, size.y); + + cl_mem buff = clCreateFromGLTexture( + context, access_type, GL_TEXTURE_2D, + 0, texture->getNativeHandle(), &error); + + if (vr_assert(error, "clCreateFromGLTexture")) + return false; + + sf::Sprite sprite(*texture); + sprite.setPosition(position); + + image_map[buffer_name] = std::pair>(sprite, std::move(texture)); + + store_buffer(buff, buffer_name); + + return true; +} + +int OpenCL::create_buffer(std::string buffer_name, cl_uint size, void* data) { + + if (buffer_map.count(buffer_name) > 0) { + release_buffer(buffer_name); + } + + cl_mem buff = clCreateBuffer( + context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, + size, data, &error + ); + + if (vr_assert(error, "clCreateBuffer")) + return -1; + + store_buffer(buff, buffer_name); + + return 1; +} + +int OpenCL::create_buffer(std::string buffer_name, cl_uint size, void* data, cl_mem_flags flags) { + + if (buffer_map.count(buffer_name) > 0) { + release_buffer(buffer_name); + } + + ((char*)data)[10000]; + + cl_mem buff = clCreateBuffer( + context, flags, + size, data, &error + ); + + if (vr_assert(error, "clCreateBuffer")) + return -1; + + store_buffer(buff, buffer_name); + + return 1; + +} + +bool OpenCL::store_buffer(cl_mem buffer, std::string buffer_name) { + + if (buffer_map.count(buffer_name) > 0) { + + error = clReleaseMemObject(buffer_map.at(buffer_name)); + + if (vr_assert(error, "clReleaseMemObject")) { + std::cout << "Error releasing overlapping buffer : " << buffer_name; + std::cout << "Buffer not added"; + return false; + } + } + + buffer_map[buffer_name] = buffer; + + return true; +} + +bool OpenCL::release_buffer(std::string buffer_name) { + + if (buffer_map.count(buffer_name) > 0) { + + error = clReleaseMemObject(buffer_map.at(buffer_name)); + + if (vr_assert(error, "clReleaseMemObject")) { + std::cout << "Error releasing buffer : " << buffer_name; + std::cout << "Buffer not removed"; + return false; + + } + + buffer_map.erase(buffer_name); + + } else { + + std::cout << "Error releasing buffer : " << buffer_name; + std::cout << "Buffer not found"; + return false; + } + + return true; +} + +int OpenCL::set_kernel_arg(std::string kernel_name, int index, std::string buffer_name) { + + error = clSetKernelArg( + kernel_map.at(kernel_name), + index, + sizeof(cl_mem), + (void *)&buffer_map.at(buffer_name)); + + if (vr_assert(error, "clSetKernelArg")) { + std::cout << buffer_name << std::endl; + std::cout << buffer_map.at(buffer_name) << std::endl; + return -1; + } + return 1; +} + +bool OpenCL::load_config() { + + std::ifstream input_file("device_config.bin", std::ios::binary | std::ios::in); + + if (!input_file.is_open()) { + std::cout << "No config file..." << std::endl; + return false; + } + + device::packed_data data; + input_file.read(reinterpret_cast(&data), sizeof(data)); + + std::cout << "config loaded, looking for device..." << std::endl; + + for (auto d: device_list) { + + if (memcmp(&d, &data, sizeof(device::packed_data)) == 0) { + std::cout << "Found saved device" << std::endl; + device_id = d.getDeviceId(); + platform_id = d.getPlatformId(); + break; + } + } + + input_file.close(); + return true; +} + + +void OpenCL::save_config() { + + std::ofstream output_file; + output_file.open("device_config.bin", std::ofstream::binary | std::ofstream::out | std::ofstream::trunc); + + device d(device_id, platform_id); + d.print_packed_data(output_file); + + output_file.close(); +} + +bool OpenCL::init() { + + if (!aquire_hardware()) + return false; + + if (!load_config()) { + + std::cout << "Select a device number which you wish to use" << std::endl; + + for (int i = 0; i < device_list.size(); i++) { + + std::cout << "\n-----------------------------------------------------------------" << std::endl; + std::cout << "\tDevice Number : " << i << std::endl; + std::cout << "-----------------------------------------------------------------" << std::endl; + + device_list.at(i).print(std::cout); + } + + int selection = -1; + + while (selection < 0 && selection >= device_list.size()) { + + std::cout << "Device which you wish to use : "; + std::cin >> selection; + } + + device_id = device_list.at(selection).getDeviceId(); + platform_id = device_list.at(selection).getPlatformId(); + + save_config(); + } + + if (!create_shared_context()) + return false; + + if (!create_command_queue()) + return false; + + + return true; +} + + +bool OpenCL::vr_assert(int error_code, std::string function_name) { + + // Just gonna do a little jump table here, just error codes so who cares + std::string err_msg = "Error : "; + + switch (error_code) { + + case CL_SUCCESS: + return false; + + case 1: + return false; + + case CL_DEVICE_NOT_FOUND: + err_msg += "CL_DEVICE_NOT_FOUND"; + break; + case CL_DEVICE_NOT_AVAILABLE: + err_msg = "CL_DEVICE_NOT_AVAILABLE"; + break; + case CL_COMPILER_NOT_AVAILABLE: + err_msg = "CL_COMPILER_NOT_AVAILABLE"; + break; + case CL_MEM_OBJECT_ALLOCATION_FAILURE: + err_msg = "CL_MEM_OBJECT_ALLOCATION_FAILURE"; + break; + case CL_OUT_OF_RESOURCES: + err_msg = "CL_OUT_OF_RESOURCES"; + break; + case CL_OUT_OF_HOST_MEMORY: + err_msg = "CL_OUT_OF_HOST_MEMORY"; + break; + case CL_PROFILING_INFO_NOT_AVAILABLE: + err_msg = "CL_PROFILING_INFO_NOT_AVAILABLE"; + break; + case CL_MEM_COPY_OVERLAP: + err_msg = "CL_MEM_COPY_OVERLAP"; + break; + case CL_IMAGE_FORMAT_MISMATCH: + err_msg = "CL_IMAGE_FORMAT_MISMATCH"; + break; + case CL_IMAGE_FORMAT_NOT_SUPPORTED: + err_msg = "CL_IMAGE_FORMAT_NOT_SUPPORTED"; + break; + case CL_BUILD_PROGRAM_FAILURE: + err_msg = "CL_BUILD_PROGRAM_FAILURE"; + break; + case CL_MAP_FAILURE: + err_msg = "CL_MAP_FAILURE"; + break; + case CL_MISALIGNED_SUB_BUFFER_OFFSET: + err_msg = "CL_MISALIGNED_SUB_BUFFER_OFFSET"; + break; + case CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST: + err_msg = "CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST"; + break; + case CL_COMPILE_PROGRAM_FAILURE: + err_msg = "CL_COMPILE_PROGRAM_FAILURE"; + break; + case CL_LINKER_NOT_AVAILABLE: + err_msg = "CL_LINKER_NOT_AVAILABLE"; + break; + case CL_LINK_PROGRAM_FAILURE: + err_msg = "CL_LINK_PROGRAM_FAILURE"; + break; + case CL_DEVICE_PARTITION_FAILED: + err_msg = "CL_DEVICE_PARTITION_FAILED"; + break; + case CL_KERNEL_ARG_INFO_NOT_AVAILABLE: + err_msg = "CL_KERNEL_ARG_INFO_NOT_AVAILABLE"; + break; + case CL_INVALID_VALUE: + err_msg = "CL_INVALID_VALUE"; + break; + case CL_INVALID_DEVICE_TYPE: + err_msg = "CL_INVALID_DEVICE_TYPE"; + break; + case CL_INVALID_PLATFORM: + err_msg = "CL_INVALID_PLATFORM"; + break; + case CL_INVALID_DEVICE: + err_msg = "CL_INVALID_DEVICE"; + break; + case CL_INVALID_CONTEXT: + err_msg = "CL_INVALID_CONTEXT"; + break; + case CL_INVALID_QUEUE_PROPERTIES: + err_msg = "CL_INVALID_QUEUE_PROPERTIES"; + break; + case CL_INVALID_COMMAND_QUEUE: + err_msg = "CL_INVALID_COMMAND_QUEUE"; + break; + case CL_INVALID_HOST_PTR: + err_msg = "CL_INVALID_HOST_PTR"; + break; + case CL_INVALID_MEM_OBJECT: + err_msg = "CL_INVALID_MEM_OBJECT"; + break; + case CL_INVALID_IMAGE_FORMAT_DESCRIPTOR: + err_msg = "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR"; + break; + case CL_INVALID_IMAGE_SIZE: + err_msg = "CL_INVALID_IMAGE_SIZE"; + break; + case CL_INVALID_SAMPLER: + err_msg = "CL_INVALID_SAMPLER"; + break; + case CL_INVALID_BINARY: + err_msg = "CL_INVALID_BINARY"; + break; + case CL_INVALID_BUILD_OPTIONS: + err_msg = "CL_INVALID_BUILD_OPTIONS"; + break; + case CL_INVALID_PROGRAM: + err_msg = "CL_INVALID_PROGRAM"; + break; + case CL_INVALID_PROGRAM_EXECUTABLE: + err_msg = "CL_INVALID_PROGRAM_EXECUTABLE"; + break; + case CL_INVALID_KERNEL_NAME: + err_msg = "CL_INVALID_KERNEL_NAME"; + break; + case CL_INVALID_KERNEL_DEFINITION: + err_msg = "CL_INVALID_KERNEL_DEFINITION"; + break; + case CL_INVALID_KERNEL: + err_msg = "CL_INVALID_KERNEL"; + break; + case CL_INVALID_ARG_INDEX: + err_msg = "CL_INVALID_ARG_INDEX"; + break; + case CL_INVALID_ARG_VALUE: + err_msg = "CL_INVALID_ARG_VALUE"; + break; + case CL_INVALID_ARG_SIZE: + err_msg = "CL_INVALID_ARG_SIZE"; + break; + case CL_INVALID_KERNEL_ARGS: + err_msg = "CL_INVALID_KERNEL_ARGS"; + break; + case CL_INVALID_WORK_DIMENSION: + err_msg = "CL_INVALID_WORK_DIMENSION"; + break; + case CL_INVALID_WORK_GROUP_SIZE: + err_msg = "CL_INVALID_WORK_GROUP_SIZE"; + break; + case CL_INVALID_WORK_ITEM_SIZE: + err_msg = "CL_INVALID_WORK_ITEM_SIZE"; + break; + case CL_INVALID_GLOBAL_OFFSET: + err_msg = "CL_INVALID_GLOBAL_OFFSET"; + break; + case CL_INVALID_EVENT_WAIT_LIST: + err_msg = "CL_INVALID_EVENT_WAIT_LIST"; + break; + case CL_INVALID_EVENT: + err_msg = "CL_INVALID_EVENT"; + break; + case CL_INVALID_OPERATION: + err_msg = "CL_INVALID_OPERATION"; + break; + case CL_INVALID_GL_OBJECT: + err_msg = "CL_INVALID_GL_OBJECT"; + break; + case CL_INVALID_BUFFER_SIZE: + err_msg = "CL_INVALID_BUFFER_SIZE"; + break; + case CL_INVALID_MIP_LEVEL: + err_msg = "CL_INVALID_MIP_LEVEL"; + break; + case CL_INVALID_GLOBAL_WORK_SIZE: + err_msg = "CL_INVALID_GLOBAL_WORK_SIZE"; + break; + case CL_INVALID_PROPERTY: + err_msg = "CL_INVALID_PROPERTY"; + break; + case CL_INVALID_IMAGE_DESCRIPTOR: + err_msg = "CL_INVALID_IMAGE_DESCRIPTOR"; + break; + case CL_INVALID_COMPILER_OPTIONS: + err_msg = "CL_INVALID_COMPILER_OPTIONS"; + break; + case CL_INVALID_LINKER_OPTIONS: + err_msg = "CL_INVALID_LINKER_OPTIONS"; + break; + case CL_INVALID_DEVICE_PARTITION_COUNT: + err_msg = "CL_INVALID_DEVICE_PARTITION_COUNT"; + break; + case CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR: + err_msg = "CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR"; + break; + case CL_PLATFORM_NOT_FOUND_KHR: + err_msg = "CL_PLATFORM_NOT_FOUND_KHR"; + break; + } + + std::cout << err_msg << " =at= " << function_name << std::endl; + return true; +} + +OpenCL::device::device(cl_device_id device_id, cl_platform_id platform_id) { + + this->device_id = device_id; + this->platform_id = platform_id; + + int error = 0; + error = clGetPlatformInfo(platform_id, CL_PLATFORM_NAME, 128, (void*)&data.platform_name, nullptr); + if (vr_assert(error, "clGetPlatformInfo")) + return; + + error = clGetDeviceInfo(device_id, CL_DEVICE_VERSION, sizeof(char) * 128, &data.opencl_version, NULL); + error = clGetDeviceInfo(device_id, CL_DEVICE_TYPE, sizeof(cl_device_type), &data.device_type, NULL); + error = clGetDeviceInfo(device_id, CL_DEVICE_MAX_CLOCK_FREQUENCY, sizeof(cl_uint), &data.clock_frequency, NULL); + error = clGetDeviceInfo(device_id, CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(cl_uint), &data.compute_units, NULL); + error = clGetDeviceInfo(device_id, CL_DEVICE_EXTENSIONS, 1024, &data.device_extensions, NULL); + error = clGetDeviceInfo(device_id, CL_DEVICE_NAME, 256, &data.device_name, NULL); + error = clGetDeviceInfo(device_id, CL_DEVICE_ENDIAN_LITTLE, sizeof(cl_bool), &is_little_endian, NULL); + + // Check for the sharing extension + if (std::string(data.device_extensions).find("cl_khr_gl_sharing") != std::string::npos || + std::string(data.device_extensions).find("cl_APPLE_gl_sharing") != std::string::npos) { + cl_gl_sharing = true; + } +} + + +OpenCL::device::device(const device& d) { + + // member values, copy individually + device_id = d.device_id; + platform_id = d.platform_id; + is_little_endian = d.is_little_endian; + cl_gl_sharing = d.cl_gl_sharing; + + // struct so it copies by value + data = d.data; + +} + +void OpenCL::device::print(std::ostream& stream) const { + + stream << "\n\tDevice ID : " << device_id << std::endl; + stream << "\tDevice Name : " << data.device_name << std::endl; + + stream << "\tPlatform ID : " << platform_id << std::endl; + stream << "\tPlatform Name : " << data.platform_name << std::endl; + + stream << "\tOpenCL Version : " << data.opencl_version << std::endl; + stream << "\tSupports sharing : " << std::boolalpha << cl_gl_sharing << std::endl; + stream << "\tDevice Type : "; + + if (data.device_type == CL_DEVICE_TYPE_CPU) + stream << "CPU" << std::endl; + + else if (data.device_type == CL_DEVICE_TYPE_GPU) + stream << "GPU" << std::endl; + + else if (data.device_type == CL_DEVICE_TYPE_ACCELERATOR) + stream << "Accelerator" << std::endl; + + stream << "\tIs Little Endian : " << std::boolalpha << is_little_endian << std::endl; + + stream << "\tClock Frequency : " << data.clock_frequency << std::endl; + stream << "\tCompute Units : " << data.compute_units << std::endl; + + stream << "\n*Extensions*" << std::endl; + stream << data.device_extensions << std::endl; + stream << "\n"; + +} + +void OpenCL::device::print_packed_data(std::ostream& stream) { + stream.write(reinterpret_cast(&data), sizeof(data)); +} diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..5a19c63 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,133 @@ + +#include +#include +#include +#include +#include "util.hpp" +#include +#include "OpenCL.h" + +float elap_time() { + static std::chrono::time_point start; + static bool started = false; + + if (!started) { + start = std::chrono::system_clock::now(); + started = true; + } + + std::chrono::time_point now = std::chrono::system_clock::now(); + std::chrono::duration elapsed_time = now - start; + return static_cast(elapsed_time.count()); +} + +const int WINDOW_X = 1080; +const int WINDOW_Y = 1080; + +void generate_nodes(sf::Uint8* nodes) { + + for (int i = 0; i < WINDOW_X * WINDOW_Y; i += 1) { + if (rand() % 10 > 8) + nodes[i] = 1; + else + nodes[i] = 0; + } + +} + +int main() { + + sf::RenderWindow window(sf::VideoMode(WINDOW_X, WINDOW_Y), "conways-game-of-life-opencl"); + window.setFramerateLimit(60); + + float physic_step = 0.166f; + float physic_time = 0.0f; + double frame_time = 0.0, elapsed_time = 0.0, delta_time = 0.0, accumulator_time = 0.0, current_time = 0.0; + + OpenCL cl; + + + if (!cl.init()) + return -1; + + while (!cl.compile_kernel("../kernels/conways.cl", "conways")) { + std::cin.get(); + } + + sf::Vector2i image_resolution(WINDOW_X, WINDOW_Y); + cl.create_image_buffer("viewport_image", image_resolution, sf::Vector2f(0, 0), CL_MEM_WRITE_ONLY); + cl.create_buffer("image_res", sizeof(sf::Vector2i), &image_resolution); + + sf::Uint8* nodes = new sf::Uint8[WINDOW_X * WINDOW_Y]; + generate_nodes(nodes); + nodes[0] = 1; + cl.create_buffer("first_node_buffer", WINDOW_X * WINDOW_Y, (void*)nodes, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR); + cl.create_buffer("second_node_buffer", WINDOW_X * WINDOW_Y, (void*)nodes, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR); + + char buffer_flip = 0; + cl.create_buffer("buffer_flip", sizeof(char), (void*)&buffer_flip, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR); + + cl.set_kernel_arg("conways", 0, "image_res"); + cl.set_kernel_arg("conways", 1, "viewport_image"); + cl.set_kernel_arg("conways", 2, "first_node_buffer"); + cl.set_kernel_arg("conways", 3, "second_node_buffer"); + cl.set_kernel_arg("conways", 4, "buffer_flip"); + + while (window.isOpen()) + { + sf::Event event; // Handle input + while (window.pollEvent(event)) { + if (event.type == sf::Event::Closed) { + window.close(); + } + if (event.type == sf::Event::KeyPressed) { + if (event.key.code == sf::Keyboard::Down) { + + } + if (event.key.code == sf::Keyboard::Up) { + + } + if (event.key.code == sf::Keyboard::Right) { + + } + if (event.key.code == sf::Keyboard::Left) { + + } + if (event.key.code == sf::Keyboard::Equal) { + + } + if (event.key.code == sf::Keyboard::Dash) { + + } + } + } + + elapsed_time = elap_time(); // Handle time + delta_time = elapsed_time - current_time; + current_time = elapsed_time; + if (delta_time > 0.02f) + delta_time = 0.02f; + accumulator_time += delta_time; + + while (accumulator_time >= physic_step) { // While the frame has sim time, update + accumulator_time -= physic_step; + physic_time += physic_step; + } + + window.clear(sf::Color::White); + + cl.run_kernel("conways", image_resolution); + //cl.run_kernel("conways", sf::Vector2i(5, 5)); + cl.draw(&window); + + if (buffer_flip == 1) + buffer_flip = 0; + else + buffer_flip = 1; + + window.display(); + + } + return 0; + +}