From a0f573fa6ecd14907c21c6f59a740128f418b095 Mon Sep 17 00:00:00 2001
From: Philip Trettner <philip.trettner@rwth-aachen.de>
Date: Sat, 29 Dec 2018 12:28:33 +0100
Subject: [PATCH] working on style guide, typed pipeline, features, backend

---
 StyleGuide.md                                 | 15 +++++++-
 src/tg/backend/backend.hh                     |  8 ++--
 .../pipelines/PrimitivePipelineBuilder.hh     |  2 +-
 src/tg/data/features.hh                       | 34 +++++++++++++++++
 src/tg/objects/Device.cc                      | 13 ++++---
 src/tg/objects/Device.hh                      | 38 +++++++++++--------
 src/tg/objects/Image.hh                       |  4 +-
 src/tg/objects/ImageView.hh                   |  1 +
 src/tg/objects/pipelines/PrimitivePipeline.hh |  2 +-
 src/tg/typed-graphics-lean.hh                 |  8 +++-
 10 files changed, 94 insertions(+), 31 deletions(-)
 create mode 100644 src/tg/data/features.hh

diff --git a/StyleGuide.md b/StyleGuide.md
index 2c11091..c399f42 100644
--- a/StyleGuide.md
+++ b/StyleGuide.md
@@ -1,6 +1,11 @@
 # Style Guide
 
 
+## Formatting
+
+* The `.clang-format` in this repository is mandatory
+
+
 ## Types
 
 * Reference types in `UpperCamelCase` (and `class`)
@@ -27,9 +32,17 @@
 ## Parameters
 
 * East-side const, especially `int const&` instead of `const int&`
+* `SharedType`s should be passed as `const&`
 
 
 ## Casts
 
 * For built-in primitives, C casts are OK
-* For any complex types, `static_cast`, `dynamic_cast`, etc. are mandatory
+* For complex type, `static_cast`, `dynamic_cast`, etc. are mandatory
+
+
+## Namespaces
+
+* Namespaces are `lower_snake_case`
+* Namespaces should be short
+* `detail` namespace is used for internal code and should not be used externally
diff --git a/src/tg/backend/backend.hh b/src/tg/backend/backend.hh
index 107952c..60eba83 100644
--- a/src/tg/backend/backend.hh
+++ b/src/tg/backend/backend.hh
@@ -2,10 +2,8 @@
 
 namespace tg
 {
-enum class backend
+class Backend
 {
-    vulkan,
-    lava,
-	glow
+    virtual ~Backend() {}
 };
-}
\ No newline at end of file
+} // namespace tg
\ No newline at end of file
diff --git a/src/tg/builder/pipelines/PrimitivePipelineBuilder.hh b/src/tg/builder/pipelines/PrimitivePipelineBuilder.hh
index b5e0909..c709fa9 100644
--- a/src/tg/builder/pipelines/PrimitivePipelineBuilder.hh
+++ b/src/tg/builder/pipelines/PrimitivePipelineBuilder.hh
@@ -8,7 +8,7 @@
 
 namespace tg
 {
-template <class VertexT, class FragmentT, class ConstantT = void>
+template <class VertexT, class FragmentT, class ConstantT = void, class... ResourceSets>
 struct PrimitivePipelineBuilder
 {
     PrimitivePipelineBuilder(SharedVertexShader<VertexT> const& vs, SharedFragmentShader<FragmentT> const& fs, topology topology = topology::triangles)
diff --git a/src/tg/data/features.hh b/src/tg/data/features.hh
new file mode 100644
index 0000000..42ee574
--- /dev/null
+++ b/src/tg/data/features.hh
@@ -0,0 +1,34 @@
+#pragma once
+
+namespace tg
+{
+// feature::defaults() is about OGL 4.0
+// feature::minimal() is about OGL 3.0
+// feature::all() is bleeding edge everything (e.g. raytracing, sparse binding, ...)
+struct features
+{
+    // "big" features
+    bool raytracing = false;
+    bool tessellation = true;
+    bool transform_feedback = true;
+    // TODO: more
+
+    // "small" features
+    bool anisotropic_filtering = true;
+    // TODO: more
+
+    static features defaults() { return {}; }
+    static features minimal()
+    {
+        features f;
+        f.tessellation = false;
+        return f;
+    }
+    static features all()
+    {
+        features f;
+        f.raytracing = true;
+        return f;
+    }
+};
+} // namespace tg
\ No newline at end of file
diff --git a/src/tg/objects/Device.cc b/src/tg/objects/Device.cc
index 96af527..c5ea543 100644
--- a/src/tg/objects/Device.cc
+++ b/src/tg/objects/Device.cc
@@ -31,17 +31,20 @@ SharedCommandBuffer Device::createCommandBuffer()
     return std::make_shared<CommandBuffer>();
 }
 
-Device::Device(backend backend, bool isDebug) : mBackend(backend), mIsDebug(isDebug) {}
+Device::Device(tg::features features, SharedBackend backend, bool isDebug, use_create_method)
+  : _features(features), _backend(std::move(backend)), _isDebug(isDebug)
+{
+}
 
-SharedDevice Device::create(backend backend)
+SharedDevice Device::create(tg::features features, SharedBackend backend)
 {
     // TODO
-    return std::make_shared<Device>(backend, false);
+    return std::make_shared<Device>(features, std::move(backend), false, use_create_method{});
 }
 
-SharedDevice Device::createDebug(backend backend)
+SharedDevice Device::createDebug(tg::features features, SharedBackend backend)
 {
     // TODO
-    return std::make_shared<Device>(backend, true);
+    return std::make_shared<Device>(features, std::move(backend), true, use_create_method{});
 }
 } // namespace tg
diff --git a/src/tg/objects/Device.hh b/src/tg/objects/Device.hh
index 4196b1c..c4b203d 100644
--- a/src/tg/objects/Device.hh
+++ b/src/tg/objects/Device.hh
@@ -10,7 +10,9 @@
 
 #include <tg/builder/builder.hh>
 
-#include <tg/backend/backend.hh>
+#include <tg/backend/Backend.hh>
+
+#include <tg/data/features.hh>
 
 #include "CommandBuffer.hh"
 
@@ -22,9 +24,11 @@ class Device : std::enable_shared_from_this<Device>
 {
     TG_REFERENCE_TYPE(Device);
 
+    // properties
 public:
-    bool isDebug() const { return mIsDebug; }
-    backend getBackend() const { return mBackend; }
+    bool isDebug() const { return _isDebug; }
+    SharedBackend const& backend() const { return _backend; }
+    features features() const { return _features; }
 
     // windows
 public:
@@ -59,8 +63,9 @@ public:
     SharedRenderPass createRenderPass(RenderPassBuilder const& builder);
     SharedRenderPass createRenderPass(SubPassBuilder const& builder);
 
-    template <class VertexT, class FragmentT, class ConstantT>
-    SharedPrimitivePipeline<VertexT, FragmentT, ConstantT> createPrimitivePipeline(PrimitivePipelineBuilder<VertexT, FragmentT, ConstantT> const& builder);
+    template <class VertexT, class FragmentT, class ConstantT, class... ResourceSets>
+    SharedPrimitivePipeline<VertexT, FragmentT, ConstantT, ResourceSets...> createPrimitivePipeline(
+        PrimitivePipelineBuilder<VertexT, FragmentT, ConstantT, ResourceSets...> const& builder);
 
     // commands
 public:
@@ -68,30 +73,33 @@ public:
 
     TG_NO_DISCARD CommandBuffer::Recorder submitGraphicsCommands()
     {
-        // TODO: user one-time submit option
-
         // TODO
         return {true};
     }
 
 public:
-    static SharedDevice create(backend backend = backend::vulkan);
-    static SharedDevice createDebug(backend backend = backend::vulkan);
+    static SharedDevice create(tg::features features = {}, SharedBackend backend = nullptr);
+    static SharedDevice createDebug(tg::features features = {}, SharedBackend backend = nullptr);
 
 public:
-    Device(backend backend, bool isDebug);
+    struct use_create_method
+    {
+    };
+    Device(tg::features features, SharedBackend backend, bool isDebug, use_create_method);
 
 private:
-    backend mBackend;
-    bool mIsDebug;
+    tg::features _features;
+    SharedBackend _backend;
+    bool _isDebug;
 };
 
 // ========= IMPLEMENTATION ==========
 
-template <class VertexT, class FragmentT, class ConstantT>
-SharedPrimitivePipeline<VertexT, FragmentT, ConstantT> Device::createPrimitivePipeline(PrimitivePipelineBuilder<VertexT, FragmentT, ConstantT> const& builder)
+template <class VertexT, class FragmentT, class ConstantT, class... ResourceSets>
+SharedPrimitivePipeline<VertexT, FragmentT, ConstantT, ResourceSets...> Device::createPrimitivePipeline(
+    PrimitivePipelineBuilder<VertexT, FragmentT, ConstantT, ResourceSets...> const& builder)
 {
     // TODO
-    return std::make_shared<PrimitivePipeline<VertexT, FragmentT, ConstantT>>();
+    return std::make_shared<PrimitivePipeline<VertexT, FragmentT, ConstantT, ResourceSets...>>();
 }
 } // namespace tg
diff --git a/src/tg/objects/Image.hh b/src/tg/objects/Image.hh
index fdfdf5f..3912109 100644
--- a/src/tg/objects/Image.hh
+++ b/src/tg/objects/Image.hh
@@ -26,7 +26,7 @@ public:
     /// NOTE: this is an expensive operation that rebuilds many resources
     ///       (should be used seldom, e.g. when window is resized)
     /// NOTE: only resizes if size is different (s == size() is a guaranteed no-op)
-    void resize(size<D, int> s)
+    void resize(tg::size<D, int> s)
     {
         if (s == _size)
             return;
@@ -41,6 +41,6 @@ public:
     Image() = default;
 
 private:
-    size<D, int> _size;
+    tg::size<D, int> _size;
 };
 } // namespace tg
diff --git a/src/tg/objects/ImageView.hh b/src/tg/objects/ImageView.hh
index 292b2f3..e903ee4 100644
--- a/src/tg/objects/ImageView.hh
+++ b/src/tg/objects/ImageView.hh
@@ -4,6 +4,7 @@
 
 namespace tg
 {
+	// TODO: Cube and CubeArray
 template <int D, class DataT>
 class ImageView
 {
diff --git a/src/tg/objects/pipelines/PrimitivePipeline.hh b/src/tg/objects/pipelines/PrimitivePipeline.hh
index 601fcf4..85a359d 100644
--- a/src/tg/objects/pipelines/PrimitivePipeline.hh
+++ b/src/tg/objects/pipelines/PrimitivePipeline.hh
@@ -29,7 +29,7 @@ namespace tg
  * TODO:
  *	* for now, viewport and scissor is always dynamic
  */
-template <class VertexT, class FragmentT, class ConstantT>
+template <class VertexT, class FragmentT, class ConstantT, class... ResourceSets>
 class PrimitivePipeline
 {
     TG_REFERENCE_TYPE(PrimitivePipeline);
diff --git a/src/tg/typed-graphics-lean.hh b/src/tg/typed-graphics-lean.hh
index 6f566f0..61f3721 100644
--- a/src/tg/typed-graphics-lean.hh
+++ b/src/tg/typed-graphics-lean.hh
@@ -9,6 +9,7 @@
 // TODO: maybe better management?
 namespace tg
 {
+TG_SHARED(class, Backend);
 TG_SHARED(class, Device);
 
 TG_SHARED(class, Window);
@@ -16,9 +17,14 @@ TG_SHARED(class, Window);
 TG_SHARED(class, CommandBuffer);
 
 TG_SHARED(class, RenderPass);
-TG_SHARED_T3D1(class, PrimitivePipeline, VertexT, FragmentT, ConstantT, void);
 TG_SHARED_T1(class, Framebuffer, FragmentT);
 
+// pipelines
+template <class VertexT, class FragmentT, class ConstantT = void, class... ResourceSets>
+class PrimitivePipeline;
+template <class VertexT, class FragmentT, class ConstantT = void, class... ResourceSets>
+using SharedPrimitivePipeline = std::shared_ptr<PrimitivePipeline<VertexT, FragmentT, ConstantT, ResourceSets...>>;
+
 TG_SHARED_T1(class, Buffer, DataT);
 TG_SHARED_T1(class, BufferView, DataT);
 
-- 
GitLab