From 9483739d3c915cb74f4eae30c04585c1501435bf Mon Sep 17 00:00:00 2001 From: Alejandro Saucedo Date: Sun, 20 Sep 2020 10:22:55 +0100 Subject: [PATCH] Initial assessment for gdnative shared script --- .../godot_examples/gdnative_shared/.gitignore | 2 + .../gdnative_shared/CMakeLists.txt | 26 +++++++ .../godot_examples/gdnative_shared/README.md | 45 +++++++++++ .../gdnative_shared/src/config.py | 5 ++ .../gdnative_shared/src/register_types.cpp | 14 ++++ .../gdnative_shared/src/register_types.h | 6 ++ .../gdnative_shared/src/summator.cpp | 77 +++++++++++++++++++ .../gdnative_shared/src/summator.h | 32 ++++++++ 8 files changed, 207 insertions(+) create mode 100644 examples/godot_examples/gdnative_shared/.gitignore create mode 100644 examples/godot_examples/gdnative_shared/CMakeLists.txt create mode 100644 examples/godot_examples/gdnative_shared/README.md create mode 100644 examples/godot_examples/gdnative_shared/src/config.py create mode 100644 examples/godot_examples/gdnative_shared/src/register_types.cpp create mode 100644 examples/godot_examples/gdnative_shared/src/register_types.h create mode 100644 examples/godot_examples/gdnative_shared/src/summator.cpp create mode 100644 examples/godot_examples/gdnative_shared/src/summator.h diff --git a/examples/godot_examples/gdnative_shared/.gitignore b/examples/godot_examples/gdnative_shared/.gitignore new file mode 100644 index 000000000..95f76b1ec --- /dev/null +++ b/examples/godot_examples/gdnative_shared/.gitignore @@ -0,0 +1,2 @@ +vulkan-kompute +lib diff --git a/examples/godot_examples/gdnative_shared/CMakeLists.txt b/examples/godot_examples/gdnative_shared/CMakeLists.txt new file mode 100644 index 000000000..236655f39 --- /dev/null +++ b/examples/godot_examples/gdnative_shared/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 3.17.0) +project(kompute_linear_reg VERSION 0.1.0) + +set(CMAKE_CXX_STANDARD 14) + +set(KOMPUTE_EXTRA_CXX_FLAGS "" CACHE STRING "Extra compile flags for Kompute, see docs for full list") + +# It is necessary to pass the DEBUG or RELEASE flag accordingly to Kompute +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG=1 ${KOMPUTE_EXTRA_CXX_FLAGS}") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DRELEASE=1 ${KOMPUTE_EXTRA_CXX_FLAGS}") + +find_package(kompute REQUIRED) +find_package(Vulkan REQUIRED) + +add_executable(kompute_linear_reg + src/*.cpp) + +target_link_libraries(kompute_linear_reg + kompute::kompute + Vulkan::Vulkan +) + +target_link_libraries(kompute_linear_reg + "lib/godot.windows.tools.64.lib" +) + diff --git a/examples/godot_examples/gdnative_shared/README.md b/examples/godot_examples/gdnative_shared/README.md new file mode 100644 index 000000000..d8e88ee00 --- /dev/null +++ b/examples/godot_examples/gdnative_shared/README.md @@ -0,0 +1,45 @@ +# Vulkan Kompute Godot Example + +## Set Up Dependencies + +### Vulkan + +You will need the Vulkan SDK, in this case we use version `1.2.148.1`, which you can get at the official site https://vulkan.lunarg.com/sdk/home#windows + +This will have the following contents that will be required later on: + +* The VulkanSDK static library `vulkan-1` + +### Kompute + +We will be using v0.3.1 of Kompute, and similar to above we will need the built static library, but in this case we will build it. + +We can start by cloning the repository on the v0.3.1 branch: + +``` +git clone --branch v0.3.1 https://github.com/EthicalML/vulkan-kompute/ +``` + +You will be able to use cmake to generate the build files for your platform. + +``` +cmake vulkan-kompute/. -Bvulkan-kompute/build +``` + +You need to make sure that the build is configured with the same flags required for godot, for example, in windows you will need: + +* Release build +* Configuration type: static library +* Runtime lib: Multi-threaded / multi-threaded debug + +Now you should see the library built under `build/src/Release` + +## Building Godot + +Now to build godot you will need to set up a couple of things for the Scons file to work - namely setting up the following: + +* Copy the `vulkan-1` library from your vulkan sdk folder to `lib/vulkan-1.lib` +* Copy the `kompute.lib` library from the Kompute build to `lib/kompute.lib` +* Make sure the versions above match as we provide the headers in the `include` folder - if you used different versions make sure these match as well + + diff --git a/examples/godot_examples/gdnative_shared/src/config.py b/examples/godot_examples/gdnative_shared/src/config.py new file mode 100644 index 000000000..1c8cd12a2 --- /dev/null +++ b/examples/godot_examples/gdnative_shared/src/config.py @@ -0,0 +1,5 @@ +def can_build(env, platform): + return True + +def configure(env): + pass diff --git a/examples/godot_examples/gdnative_shared/src/register_types.cpp b/examples/godot_examples/gdnative_shared/src/register_types.cpp new file mode 100644 index 000000000..3cb5b536f --- /dev/null +++ b/examples/godot_examples/gdnative_shared/src/register_types.cpp @@ -0,0 +1,14 @@ +/* register_types.cpp */ + +#include "register_types.h" + +#include "core/class_db.h" +#include "summator.h" + +void register_summator_types() { + ClassDB::register_class(); +} + +void unregister_summator_types() { + // Nothing to do here in this example. +} diff --git a/examples/godot_examples/gdnative_shared/src/register_types.h b/examples/godot_examples/gdnative_shared/src/register_types.h new file mode 100644 index 000000000..fa64f1c7b --- /dev/null +++ b/examples/godot_examples/gdnative_shared/src/register_types.h @@ -0,0 +1,6 @@ +/* register_types.h */ +#pragma once + +void register_summator_types(); +void unregister_summator_types(); +/* yes, the word in the middle must be the same as the module folder name */ diff --git a/examples/godot_examples/gdnative_shared/src/summator.cpp b/examples/godot_examples/gdnative_shared/src/summator.cpp new file mode 100644 index 000000000..ab87d1376 --- /dev/null +++ b/examples/godot_examples/gdnative_shared/src/summator.cpp @@ -0,0 +1,77 @@ +/* summator.cpp */ + +#include + +#include "summator.h" + +Summator::Summator() { + this->mPrimaryTensor = this->mManager.buildTensor({ 0.0 }); + this->mSecondaryTensor = this->mManager.buildTensor({ 0.0 }); + this->mSequence = this->mManager.getOrCreateManagedSequence("AdditionSeq"); + + // We now record the steps in the sequence + if (std::shared_ptr sq = this->mSequence.lock()) + { + + std::string shader(R"( + #version 450 + + layout (local_size_x = 1) in; + + layout(set = 0, binding = 0) buffer a { float pa[]; }; + layout(set = 0, binding = 1) buffer b { float pb[]; }; + + void main() { + uint index = gl_GlobalInvocationID.x; + pa[index] = pb[index] + pa[index]; + } + )"); + + sq->begin(); + + // First we ensure secondary tensor loads to GPU + // No need to sync the primary tensor as it should not be changed + sq->record( + { this->mSecondaryTensor }); + + // Then we run the operation with both tensors + sq->record>( + { this->mPrimaryTensor, this->mSecondaryTensor }, + std::vector(shader.begin(), shader.end())); + + // We map the result back to local + sq->record( + { this->mPrimaryTensor }); + + sq->end(); + } + else { + throw std::runtime_error("Sequence pointer no longer available"); + } +} + +void Summator::add(float value) { + // Set the new data in the local device + this->mSecondaryTensor->setData({value}); + // Execute recorded sequence + if (std::shared_ptr sq = this->mSequence.lock()) { + sq->eval(); + } + else { + throw std::runtime_error("Sequence pointer no longer available"); + } +} + +void Summator::reset() { +} + +float Summator::get_total() const { + return this->mPrimaryTensor->data()[0]; +} + +void Summator::_bind_methods() { + ClassDB::bind_method(D_METHOD("add", "value"), &Summator::add); + ClassDB::bind_method(D_METHOD("reset"), &Summator::reset); + ClassDB::bind_method(D_METHOD("get_total"), &Summator::get_total); +} + diff --git a/examples/godot_examples/gdnative_shared/src/summator.h b/examples/godot_examples/gdnative_shared/src/summator.h new file mode 100644 index 000000000..9c13c5565 --- /dev/null +++ b/examples/godot_examples/gdnative_shared/src/summator.h @@ -0,0 +1,32 @@ +/* summator.h */ + +#ifndef SUMMATOR_H +#define SUMMATOR_H + +#include + +#include "kompute/Kompute.hpp" + +#include "scene/main/node.h" + +class Summator : public Node { + GDCLASS(Summator, Node); + +public: + Summator(); + + void add(float value); + void reset(); + float get_total() const; + +protected: + static void _bind_methods(); + +private: + kp::Manager mManager; + std::weak_ptr mSequence; + std::shared_ptr mPrimaryTensor; + std::shared_ptr mSecondaryTensor; +}; + +#endif // SUMMATOR_H