[Vulkan] Basic Vulkan backend
authoradam.b <jsr184@gmail.com>
Wed, 31 Jan 2018 16:37:25 +0000 (16:37 +0000)
committeradam.b <jsr184@gmail.com>
Wed, 7 Feb 2018 11:29:24 +0000 (11:29 +0000)
Supported:
- Pipeline ( limited )
- Shaders ( ShaderModule ) ( very limited )
- Buffers ( vertex and uniform buffers ) ( limited )
- Descriptors ( sets, layouts. descriptors, pools ) ( limited, no samplers )
- CommandBuffers ( limited set of commands )
- Simple synchronisation ( vsync and swapchain )
- Indexed draw

Change-Id: Iafd2f6bb675ebb0994a8ed1c913128cef1fda0b0

40 files changed:
dali/graphics/file.list
dali/graphics/vulkan/generated/spv-shaders-gen.cpp [new file with mode: 0644]
dali/graphics/vulkan/generated/spv-shaders-gen.h [new file with mode: 0644]
dali/graphics/vulkan/gpu-memory/vulkan-gpu-memory-allocator.h [new file with mode: 0644]
dali/graphics/vulkan/gpu-memory/vulkan-gpu-memory-handle.cpp [new file with mode: 0644]
dali/graphics/vulkan/gpu-memory/vulkan-gpu-memory-handle.h [new file with mode: 0644]
dali/graphics/vulkan/gpu-memory/vulkan-gpu-memory-manager.cpp [new file with mode: 0644]
dali/graphics/vulkan/gpu-memory/vulkan-gpu-memory-manager.h [new file with mode: 0644]
dali/graphics/vulkan/shaders/basic-shader.frag [new file with mode: 0644]
dali/graphics/vulkan/shaders/basic-shader.vert [new file with mode: 0644]
dali/graphics/vulkan/vulkan-buffer.cpp
dali/graphics/vulkan/vulkan-buffer.h
dali/graphics/vulkan/vulkan-command-buffer.cpp
dali/graphics/vulkan/vulkan-command-buffer.h
dali/graphics/vulkan/vulkan-command-pool.cpp
dali/graphics/vulkan/vulkan-command-pool.h
dali/graphics/vulkan/vulkan-descriptor-set.cpp [new file with mode: 0644]
dali/graphics/vulkan/vulkan-descriptor-set.h [new file with mode: 0644]
dali/graphics/vulkan/vulkan-device-memory-manager.cpp [deleted file]
dali/graphics/vulkan/vulkan-device-memory-manager.h [deleted file]
dali/graphics/vulkan/vulkan-fence.cpp
dali/graphics/vulkan/vulkan-fence.h
dali/graphics/vulkan/vulkan-framebuffer.cpp [new file with mode: 0644]
dali/graphics/vulkan/vulkan-framebuffer.h [new file with mode: 0644]
dali/graphics/vulkan/vulkan-graphics.cpp
dali/graphics/vulkan/vulkan-graphics.h
dali/graphics/vulkan/vulkan-image.cpp
dali/graphics/vulkan/vulkan-image.h
dali/graphics/vulkan/vulkan-pipeline.cpp [new file with mode: 0644]
dali/graphics/vulkan/vulkan-pipeline.h [new file with mode: 0644]
dali/graphics/vulkan/vulkan-queue.cpp
dali/graphics/vulkan/vulkan-queue.h
dali/graphics/vulkan/vulkan-shader.cpp [new file with mode: 0644]
dali/graphics/vulkan/vulkan-shader.h [new file with mode: 0644]
dali/graphics/vulkan/vulkan-standalone-test.cpp
dali/graphics/vulkan/vulkan-surface.cpp
dali/graphics/vulkan/vulkan-surface.h
dali/graphics/vulkan/vulkan-types.h
dali/integration-api/graphics/graphics.cpp
dali/integration-api/graphics/graphics.h

index b73e81b..edb00b2 100644 (file)
@@ -1,15 +1,20 @@
 # Add graphics source files here
 
 graphics_src_files = \
-  $(graphics_src_dir)/graphics-controller.cpp \
-  $(graphics_src_dir)/vulkan/vulkan-graphics.cpp \
-  $(graphics_src_dir)/vulkan/vulkan-fence.cpp \
-  $(graphics_src_dir)/vulkan/vulkan-queue.cpp \
-  $(graphics_src_dir)/vulkan/vulkan-surface.cpp \
-  $(graphics_src_dir)/vulkan/vulkan-command-buffer.cpp \
-  $(graphics_src_dir)/vulkan/vulkan-command-pool.cpp \
-  $(graphics_src_dir)/vulkan/vulkan-image.cpp \
-  $(graphics_src_dir)/vulkan/vulkan-buffer.cpp \
-  $(graphics_src_dir)/vulkan/vulkan-device-memory-manager.cpp
+    $(graphics_src_dir)/vulkan/vulkan-command-pool.cpp \
+    $(graphics_src_dir)/vulkan/vulkan-surface.cpp \
+    $(graphics_src_dir)/vulkan/vulkan-fence.cpp \
+    $(graphics_src_dir)/vulkan/vulkan-descriptor-set.cpp \
+    $(graphics_src_dir)/vulkan/vulkan-framebuffer.cpp \
+    $(graphics_src_dir)/vulkan/vulkan-queue.cpp \
+    $(graphics_src_dir)/vulkan/generated/spv-shaders-gen.cpp \
+    $(graphics_src_dir)/vulkan/gpu-memory/vulkan-gpu-memory-handle.cpp \
+    $(graphics_src_dir)/vulkan/gpu-memory/vulkan-gpu-memory-manager.cpp \
+    $(graphics_src_dir)/vulkan/vulkan-image.cpp \
+    $(graphics_src_dir)/vulkan/vulkan-command-buffer.cpp \
+    $(graphics_src_dir)/vulkan/vulkan-pipeline.cpp \
+    $(graphics_src_dir)/vulkan/vulkan-buffer.cpp \
+    $(graphics_src_dir)/vulkan/vulkan-graphics.cpp \
+    $(graphics_src_dir)/vulkan/vulkan-shader.cpp
 
 
diff --git a/dali/graphics/vulkan/generated/spv-shaders-gen.cpp b/dali/graphics/vulkan/generated/spv-shaders-gen.cpp
new file mode 100644 (file)
index 0000000..2ec5c3c
--- /dev/null
@@ -0,0 +1,169 @@
+#include "spv-shaders-gen.h"
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wlarger-than="
+std::vector<uint8_t> VSH_CODE = {
+  0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x00,
+  0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30,
+  0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00,
+  0x0d, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00,
+  0x03, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0xae, 0x01, 0x00, 0x00,
+  0x05, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e,
+  0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x06, 0x00, 0x0b, 0x00, 0x00, 0x00,
+  0x67, 0x6c, 0x5f, 0x50, 0x65, 0x72, 0x56, 0x65, 0x72, 0x74, 0x65, 0x78,
+  0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x0b, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74,
+  0x69, 0x6f, 0x6e, 0x00, 0x06, 0x00, 0x07, 0x00, 0x0b, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x69, 0x6e, 0x74,
+  0x53, 0x69, 0x7a, 0x65, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x07, 0x00,
+  0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x67, 0x6c, 0x5f, 0x43,
+  0x6c, 0x69, 0x70, 0x44, 0x69, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x00,
+  0x05, 0x00, 0x03, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x05, 0x00, 0x04, 0x00, 0x11, 0x00, 0x00, 0x00, 0x77, 0x6f, 0x72, 0x6c,
+  0x64, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x00, 0x11, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x4d, 0x61, 0x74,
+  0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x05, 0x00, 0x11, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x76, 0x69, 0x65, 0x77, 0x4d, 0x61, 0x74, 0x00,
+  0x06, 0x00, 0x05, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x70, 0x72, 0x6f, 0x6a, 0x4d, 0x61, 0x74, 0x00, 0x06, 0x00, 0x05, 0x00,
+  0x11, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x63, 0x6f, 0x6c, 0x6f,
+  0x72, 0x00, 0x00, 0x00, 0x05, 0x00, 0x03, 0x00, 0x13, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x21, 0x00, 0x00, 0x00,
+  0x61, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00,
+  0x05, 0x00, 0x05, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x74, 0x72, 0x69, 0x43,
+  0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
+  0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x48, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x0b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00,
+  0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x48, 0x00, 0x04, 0x00,
+  0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+  0x48, 0x00, 0x05, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
+  0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+  0x10, 0x00, 0x00, 0x00, 0x48, 0x00, 0x04, 0x00, 0x11, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
+  0x11, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
+  0x40, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x11, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+  0x48, 0x00, 0x04, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x05, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00, 0x11, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+  0x48, 0x00, 0x05, 0x00, 0x11, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x07, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x48, 0x00, 0x05, 0x00,
+  0x11, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
+  0xc0, 0x00, 0x00, 0x00, 0x47, 0x00, 0x03, 0x00, 0x11, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x13, 0x00, 0x00, 0x00,
+  0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
+  0x13, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x47, 0x00, 0x04, 0x00, 0x21, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x2b, 0x00, 0x00, 0x00,
+  0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00,
+  0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x15, 0x00, 0x04, 0x00,
+  0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x2b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x05, 0x00,
+  0x0b, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x0a, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x0c, 0x00, 0x00, 0x00,
+  0x03, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00,
+  0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x15, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00,
+  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x04, 0x00,
+  0x10, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x1e, 0x00, 0x06, 0x00, 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+  0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+  0x20, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x11, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00, 0x00,
+  0x13, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00,
+  0x0e, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x20, 0x00, 0x04, 0x00, 0x15, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x10, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00,
+  0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00,
+  0x1f, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x20, 0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x1f, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00,
+  0x21, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f,
+  0x20, 0x00, 0x04, 0x00, 0x29, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x29, 0x00, 0x00, 0x00,
+  0x2b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00,
+  0x0e, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x20, 0x00, 0x04, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x07, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0xf8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
+  0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
+  0x14, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00,
+  0x17, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00,
+  0x15, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
+  0x18, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00,
+  0x1a, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x92, 0x00, 0x05, 0x00,
+  0x10, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
+  0x1a, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x15, 0x00, 0x00, 0x00,
+  0x1c, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
+  0x3d, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00,
+  0x1c, 0x00, 0x00, 0x00, 0x92, 0x00, 0x05, 0x00, 0x10, 0x00, 0x00, 0x00,
+  0x1e, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00,
+  0x3d, 0x00, 0x04, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
+  0x21, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x24, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x51, 0x00, 0x05, 0x00, 0x06, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
+  0x22, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x51, 0x00, 0x05, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x00, 0x50, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00,
+  0x27, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
+  0x26, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x91, 0x00, 0x05, 0x00,
+  0x07, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
+  0x27, 0x00, 0x00, 0x00, 0x41, 0x00, 0x05, 0x00, 0x29, 0x00, 0x00, 0x00,
+  0x2a, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
+  0x3e, 0x00, 0x03, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
+  0x41, 0x00, 0x05, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00,
+  0x13, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
+  0x07, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00,
+  0x3e, 0x00, 0x03, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00,
+  0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00
+};
+std::vector<uint8_t> FSH_CODE = {
+  0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x00,
+  0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30,
+  0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00,
+  0x09, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x00, 0x03, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00,
+  0x02, 0x00, 0x00, 0x00, 0xae, 0x01, 0x00, 0x00, 0x05, 0x00, 0x04, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x6d, 0x61, 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00,
+  0x05, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00, 0x6f, 0x75, 0x74, 0x43,
+  0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00,
+  0x0b, 0x00, 0x00, 0x00, 0x74, 0x72, 0x69, 0x43, 0x6f, 0x6c, 0x6f, 0x72,
+  0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00,
+  0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00,
+  0x0b, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00,
+  0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00,
+  0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+  0x20, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00,
+  0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+  0x3b, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0xf8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00,
+  0x07, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
+  0x3e, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
+  0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00
+};
+#pragma GCC diagnostic pop
diff --git a/dali/graphics/vulkan/generated/spv-shaders-gen.h b/dali/graphics/vulkan/generated/spv-shaders-gen.h
new file mode 100644 (file)
index 0000000..716b7ff
--- /dev/null
@@ -0,0 +1,46 @@
+// Autogenerated
+#ifndef SPV_GENERATED_HEADER
+#define SPV_GENERATED_HEADER
+#include <vector>
+#include <cstdint>
+
+
+extern std::vector<uint8_t> VSH_CODE;
+/*
+#version 430
+
+layout( location = 0 ) in vec3 aPosition;
+
+layout( set = 0, binding = 0, std140 ) uniform world
+{
+    mat4 modelMat;
+    mat4 viewMat;
+    mat4 projMat;
+    vec4 color;
+};
+
+layout( location = 0 ) out vec4 triColor;
+
+void main()
+{
+    gl_Position = projMat * viewMat * modelMat * vec4( aPosition, 1.0 );
+    triColor = color;
+}*/
+
+
+extern std::vector<uint8_t> FSH_CODE;
+/*
+#version 430
+
+layout( location = 0 ) in vec4 triColor;
+layout( location = 0 ) out vec4 outColor;
+
+void main()
+{
+    outColor = triColor;
+}*/
+
+
+#endif // SPV_GENERATED_HEADER
+
+
diff --git a/dali/graphics/vulkan/gpu-memory/vulkan-gpu-memory-allocator.h b/dali/graphics/vulkan/gpu-memory/vulkan-gpu-memory-allocator.h
new file mode 100644 (file)
index 0000000..66d75d2
--- /dev/null
@@ -0,0 +1,139 @@
+#ifndef DALI_GRAPHICS_VULKAN_GPU_MEMORY_ALLOCATOR
+#define DALI_GRAPHICS_VULKAN_GPU_MEMORY_ALLOCATOR
+
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <dali/graphics/vulkan/vulkan-types.h>
+#include <dali/graphics/vulkan/gpu-memory/vulkan-gpu-memory-handle.h>
+namespace Dali
+{
+namespace Graphics
+{
+namespace Vulkan
+{
+class Buffer;
+class Image;
+class GpuMemoryBlock;
+/**
+ * Interface to Gpu memory allocation, must be overriden.
+ */
+using GpuMemoryAllocationData = void*;
+
+class GpuMemoryAllocator
+{
+public:
+
+  GpuMemoryAllocator() = default;
+
+  /**
+   *
+   */
+  virtual ~GpuMemoryAllocator() = default;
+
+  /**
+   *
+   * @param requirements
+   * @param memoryProperties
+   * @return
+   */
+  virtual GpuMemoryBlockHandle Allocate( const vk::MemoryRequirements& requirements, vk::MemoryPropertyFlags memoryProperties ) = 0;
+
+  /**
+   *
+   * @param buffer
+   * @param memoryProperties
+   * @return
+   */
+  virtual GpuMemoryBlockHandle Allocate( const Handle<Buffer>& buffer, vk::MemoryPropertyFlags memoryProperties ) = 0;
+
+  /**
+   *
+   * @param buffer
+   * @param memoryProperties
+   * @return
+   */
+  virtual GpuMemoryBlockHandle Allocate( Image& buffer, vk::MemoryPropertyFlags memoryProperties ) = 0;
+
+  // refcounting managed via allocator which ownes all the blocks, allocator may
+  // implement this feature any way ( or simply ignore it )
+  /**
+   *
+   * @param allocationId
+   */
+  virtual void Retain( GpuMemoryBlock& allocationId ) {}
+
+  /**
+   *
+   * @param allocationId
+   */
+  virtual void Release( GpuMemoryBlock& allocationId ) {}
+
+  /**
+   *
+   * @param allocationId
+   */
+  virtual uint32_t GetRefCount( GpuMemoryBlock& allocationId )
+  {
+    return 0u;
+  }
+
+  // Garbage collection
+  /**
+   *
+   * @param userdata
+   */
+  virtual void GC( void* userdata ) = 0;
+
+  // Retrieve Vulkan object for this allocation
+  /**
+   *
+   * @return
+   */
+  virtual vk::DeviceMemory GetVkDeviceMemory( GpuMemoryBlock& allocationId ) const = 0;
+
+  /**
+   * Memory mapping
+   * @param allocationId
+   * @param offset
+   * @param size
+   * @return
+   */
+  virtual void* Map( GpuMemoryBlock& allocationId, uint32_t offset, uint32_t size ) = 0;
+
+  /**
+   * Memory mapping
+   * @param allocationId
+   * @param offset
+   * @param size
+   * @return
+   */
+  virtual void Unmap( GpuMemoryBlock& allocationId ) = 0;
+
+  /**
+   *
+   * @param allocationId
+   */
+  virtual void Flush( GpuMemoryBlock& allocationId ) = 0;
+};
+
+} // Namespace Vulkan
+
+} // namespace Graphics
+
+} // Namespace Dali
+
+#endif // DALI_GRAPHICS_VULKAN_GPU_MEMORY_ALLOCATOR
diff --git a/dali/graphics/vulkan/gpu-memory/vulkan-gpu-memory-handle.cpp b/dali/graphics/vulkan/gpu-memory/vulkan-gpu-memory-handle.cpp
new file mode 100644 (file)
index 0000000..0d78be4
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali/graphics/vulkan/gpu-memory/vulkan-gpu-memory-handle.h>
+#include <dali/graphics/vulkan/gpu-memory/vulkan-gpu-memory-allocator.h>
+
+namespace Dali
+{
+namespace Graphics
+{
+namespace Vulkan
+{
+
+void GpuMemoryBlock::OnRelease( uint32_t refcount )
+{
+  mAllocator.Release( *this );
+}
+
+void GpuMemoryBlock::OnRetain( uint32_t refcount )
+{
+  mAllocator.Retain( *this );
+}
+
+bool GpuMemoryBlock::OnDestroy()
+{
+  // don't use default delete
+  return true;
+}
+
+GpuMemoryBlock::operator vk::DeviceMemory()
+{
+  return mAllocator.GetVkDeviceMemory( *this );
+}
+
+void* GpuMemoryBlock::Map()
+{
+  return mAllocator.Map( *this, 0, 0 );
+}
+
+void* GpuMemoryBlock::Map( uint32_t offset, uint32_t size )
+{
+  return mAllocator.Map( *this, offset, size );
+}
+
+void GpuMemoryBlock::Unmap()
+{
+  mAllocator.Unmap( *this );
+}
+
+void GpuMemoryBlock::Flush()
+{
+  NotImplemented();
+}
+
+}
+
+}
+
+}
\ No newline at end of file
diff --git a/dali/graphics/vulkan/gpu-memory/vulkan-gpu-memory-handle.h b/dali/graphics/vulkan/gpu-memory/vulkan-gpu-memory-handle.h
new file mode 100644 (file)
index 0000000..1a30f87
--- /dev/null
@@ -0,0 +1,122 @@
+#ifndef DALI_VULKAN_161117_GPU_MEMORY_HANDLE_H
+#define DALI_VULKAN_161117_GPU_MEMORY_HANDLE_H
+
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali/graphics/vulkan/vulkan-types.h>
+
+namespace Dali
+{
+namespace Graphics
+{
+namespace Vulkan
+{
+class GpuMemoryAllocator;
+const uint32_t INVALID_ALLOCATION { UINT32_MAX };
+
+struct Any {};
+class GpuMemoryBlock : public VkManaged
+{
+public:
+
+  template <class T>
+  GpuMemoryBlock( GpuMemoryAllocator& allocator, std::unique_ptr<T> data ) :
+  mAllocator(allocator), mAllocationData(reinterpret_cast<Any*>(data.release())){}
+
+  /**
+   *
+   * @return
+   */
+  void* Map();
+
+  /**
+   *
+   * @param offset
+   * @param size
+   * @return
+   */
+  void* Map( uint32_t offset, uint32_t size );
+
+  /**
+   *
+   */
+  void Unmap();
+
+  /**
+   *
+   */
+  void Flush();
+
+  /**
+   *
+   * @return
+   */
+  operator vk::DeviceMemory();
+
+  /**
+   *
+   * @tparam T
+   * @return
+   */
+  template <class T>
+  T* GetData() const
+  {
+    return reinterpret_cast<T*>(mAllocationData.get());
+  }
+
+  /**
+   *
+   * @return
+   */
+  GpuMemoryAllocator& GetAllocator() const
+  {
+    return mAllocator;
+  }
+
+public:
+
+  /**
+   *
+   * @param refcount
+   */
+  void OnRelease( uint32_t refcount ) override;
+
+  /**
+   *
+   * @param refcount
+   */
+  void OnRetain( uint32_t refcount ) override;
+
+  /**
+   *
+   */
+  bool OnDestroy() override;
+
+private:
+
+  GpuMemoryAllocator&         mAllocator;
+  std::unique_ptr<Any>        mAllocationData; // may be any POD object pointer, depends on allocator
+};
+
+using GpuMemoryBlockHandle = Handle<GpuMemoryBlock>;
+
+}
+}
+}
+
+#endif //DALI_VULKAN_161117_GPU_MEMORY_HANDLE_H
diff --git a/dali/graphics/vulkan/gpu-memory/vulkan-gpu-memory-manager.cpp b/dali/graphics/vulkan/gpu-memory/vulkan-gpu-memory-manager.cpp
new file mode 100644 (file)
index 0000000..7fc9a64
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali/graphics/vulkan/gpu-memory/vulkan-gpu-memory-manager.h>
+#include <dali/graphics/vulkan/gpu-memory/vulkan-gpu-memory-allocator.h>
+#include <dali/graphics/vulkan/gpu-memory/vulkan-gpu-memory-handle.h>
+#include <dali/graphics/vulkan/vulkan-graphics.h>
+#include <dali/graphics/vulkan/vulkan-buffer.h>
+#include <dali/graphics/vulkan/vulkan-image.h>
+#include <atomic>
+namespace Dali
+{
+namespace Graphics
+{
+namespace Vulkan
+{
+
+namespace
+{
+
+const uint32_t INVALID_MEMORY_INDEX = -1u;
+
+/**
+ * Helper function which returns GPU heap index that can be used to allocate
+ * particular type of resource
+ */
+uint32_t GetMemoryIndex(const vk::PhysicalDeviceMemoryProperties &memoryProperties,
+                        uint32_t memoryTypeBits, vk::MemoryPropertyFlags properties)
+{
+  for(uint32_t i = 0; i < memoryProperties.memoryTypeCount; ++i)
+  {
+    if((memoryTypeBits & (1u << i)) &&
+       ((memoryProperties.memoryTypes[i].propertyFlags & properties) == properties))
+    {
+      return i;
+    }
+  }
+  return INVALID_MEMORY_INDEX;
+}
+}
+
+/**
+ * Class: GpuMemoryDefaultAllocator
+ *
+ * Non-thread safe default GPU memory allocator
+ * with simple refcounting and garbage collection on demand
+ */
+struct GpuMemoryDefaultAllocator : public GpuMemoryAllocator
+{
+  struct MemoryBlock
+  {
+    MemoryBlock() = default;
+    ~MemoryBlock() = default;
+
+    vk::MemoryRequirements  requirements {};
+    vk::DeviceSize          offset { 0u };
+    vk::DeviceSize          size { 0u };
+    vk::DeviceSize          alignment { 0u };
+    vk::DeviceMemory        memory { nullptr };
+  };
+
+  GpuMemoryDefaultAllocator( GpuMemoryManager& manager )
+    : GpuMemoryAllocator(), mGpuManager( manager ),
+      mGraphics(manager.GetGraphics())
+  {
+
+  }
+
+  ~GpuMemoryDefaultAllocator() override = default;
+
+
+  GpuMemoryBlockHandle Allocate( const vk::MemoryRequirements& requirements, vk::MemoryPropertyFlags memoryProperties ) override
+  {
+
+    auto memoryTypeIndex = GetMemoryIndex(mGraphics.GetMemoryProperties(), requirements.memoryTypeBits,
+                                          memoryProperties);
+
+    auto memory = VkAssert(
+      mGraphics.GetDevice()
+               .allocateMemory(vk::MemoryAllocateInfo{}
+                                 .setMemoryTypeIndex(memoryTypeIndex)
+                                 .setAllocationSize(requirements.size), mGraphics.GetAllocator()));
+
+    // add allocated memory to the heap of memories as a base handle
+    auto handle = GpuMemoryBlockHandle( new GpuMemoryBlock( *this, MakeUnique<MemoryBlock>() ) );
+
+    auto &block = *handle->GetData<MemoryBlock>();
+    block.requirements = requirements;
+    block.offset       = 0u;
+    block.size         = requirements.size;
+    block.alignment    = requirements.alignment;
+    block.memory       = memory;
+
+    mUniqueBlocks.emplace_back( MakeUnique<GpuMemoryBlockHandle>(handle) );
+    return handle;
+  }
+
+  /**
+   *
+   * @param buffer
+   * @param memoryProperties
+   * @return
+   */
+  virtual GpuMemoryBlockHandle Allocate( const Handle<Buffer>& buffer, vk::MemoryPropertyFlags memoryProperties ) override
+  {
+    return Allocate( mGraphics.GetDevice().getBufferMemoryRequirements( buffer->GetVkBuffer() ),
+                     memoryProperties );
+  }
+
+  /**
+   *
+   * @param buffer
+   * @param memoryProperties
+   * @return
+   */
+  GpuMemoryBlockHandle Allocate( Image& image, vk::MemoryPropertyFlags memoryProperties ) override
+  {
+    return Allocate( mGraphics.GetDevice().getImageMemoryRequirements( image.GetImage() ),
+                               memoryProperties );
+  }
+
+  /**
+   *
+   * Reference counting
+   */
+  void Retain( GpuMemoryBlock& allocationId ) override
+  {
+  }
+
+  void Release( GpuMemoryBlock& block ) override
+  {
+    if( block.GetRefCount() == 1 )
+    {
+      GC(nullptr);
+    }
+  }
+
+  /**
+   *
+   * Garbage collection
+   */
+  void GC( void* userdata ) override
+  {
+    for( auto&& block : mUniqueBlocks )
+    {
+      if( block->GetRefCount() == 1 )
+      {
+        // collect and make invalid ( maybe freelist or sumtink )
+        mGraphics.GetDevice().freeMemory( (**block.get()), mGraphics.GetAllocator() );
+        block.reset( nullptr );
+      }
+    }
+  }
+
+  vk::DeviceMemory GetVkDeviceMemory( GpuMemoryBlock& block ) const override
+  {
+    return block.GetData<MemoryBlock>()->memory;
+  }
+
+  void* Map( GpuMemoryBlock& block, uint32_t offset, uint32_t size ) override
+  {
+    return VkAssert( mGraphics.GetDevice().mapMemory( block.GetData<MemoryBlock>()->memory,
+                                offset, size == 0u ? VK_WHOLE_SIZE : static_cast<VkDeviceSize>(size)));
+  }
+
+  void Unmap( GpuMemoryBlock& block ) override
+  {
+    mGraphics.GetDevice().unmapMemory( block.GetData<MemoryBlock>()->memory );
+  }
+
+  void Flush( GpuMemoryBlock& allocationId ) override
+  {
+    NotImplemented();
+  }
+
+  GpuMemoryManager& mGpuManager;
+  Graphics& mGraphics;
+
+  std::vector<std::unique_ptr<GpuMemoryBlockHandle>> mUniqueBlocks;
+};
+
+struct GpuMemoryManager::Impl
+{
+  Impl( Graphics& graphics, GpuMemoryManager& interface ) :
+    mGraphics( graphics ),
+    mMemoryManager( interface )
+  {
+
+  }
+
+  ~Impl()
+  {
+  }
+
+  bool Initialise()
+  {
+    CreateDefaultAllocator();
+    return true;
+  }
+
+  GpuMemoryAllocator& GetDefaultAllocator() const
+  {
+    return *mDefaultAllocator;
+  }
+
+  void CreateDefaultAllocator()
+  {
+    mDefaultAllocator = MakeUnique<GpuMemoryDefaultAllocator>( mMemoryManager );
+  }
+
+  Graphics& mGraphics;
+  GpuMemoryManager& mMemoryManager; // interface to this implementation
+  std::unique_ptr<GpuMemoryAllocator> mDefaultAllocator; // default allocator, brute force allocation
+};
+
+/**
+ * Class: GpuMemoryManager
+ */
+
+std::unique_ptr<GpuMemoryManager> GpuMemoryManager::New(Graphics& graphics)
+{
+  auto retval = std::unique_ptr<GpuMemoryManager>(new GpuMemoryManager(graphics));
+  if( retval->mImpl->Initialise() )
+  {
+    return retval;
+  }
+  return nullptr;
+}
+
+GpuMemoryManager::GpuMemoryManager() = default;
+
+GpuMemoryManager::~GpuMemoryManager() = default;
+
+GpuMemoryManager::GpuMemoryManager(Graphics& graphics)
+{
+  mImpl = std::unique_ptr<Impl, std::default_delete<GpuMemoryManager::Impl>>( new Impl(graphics, *this) );
+}
+
+GpuMemoryAllocator& GpuMemoryManager::GetDefaultAllocator() const
+{
+  return mImpl->GetDefaultAllocator();
+}
+
+
+GpuMemoryAllocatorUID GpuMemoryManager::RegisterAllocator( std::unique_ptr<GpuMemoryAllocator> allocator )
+{
+  NotImplemented();
+  return 0;
+}
+
+bool GpuMemoryManager::UnregisterAllocator( GpuMemoryAllocatorUID allocatorHandle )
+{
+  NotImplemented();
+  return false;
+}
+
+Graphics& GpuMemoryManager::GetGraphics() const
+{
+  return mImpl->mGraphics;
+}
+
+}
+
+}
+
+}
diff --git a/dali/graphics/vulkan/gpu-memory/vulkan-gpu-memory-manager.h b/dali/graphics/vulkan/gpu-memory/vulkan-gpu-memory-manager.h
new file mode 100644 (file)
index 0000000..34ad5a3
--- /dev/null
@@ -0,0 +1,91 @@
+#ifndef DALI_VULKAN_161117_GPU_MEMORY_MANAGER_H
+#define DALI_VULKAN_161117_GPU_MEMORY_MANAGER_H
+
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali/graphics/vulkan/vulkan-types.h>
+
+namespace Dali
+{
+namespace Graphics
+{
+namespace Vulkan
+{
+using GpuMemoryAllocatorUID = uint32_t;
+class Graphics;
+class GpuMemoryAllocator;
+
+class GpuMemoryManager
+{
+public:
+
+  static std::unique_ptr<GpuMemoryManager> New( Graphics& graphics );
+
+  /**
+   *
+   */
+  ~GpuMemoryManager();
+
+  /**
+   *
+   * @return
+   */
+  GpuMemoryAllocator& GetDefaultAllocator() const;
+
+  /**
+   *
+   * @param allocator
+   * @return
+   */
+  GpuMemoryAllocatorUID RegisterAllocator( std::unique_ptr<GpuMemoryAllocator> allocator );
+
+  /**
+   *
+   * @param allocatorHandle
+   * @return
+   */
+  bool UnregisterAllocator( GpuMemoryAllocatorUID allocatorHandle );
+
+  /**
+   *
+   * @return
+   */
+  Graphics& GetGraphics() const;
+
+private:
+
+  GpuMemoryManager();
+
+  /**
+   *
+   */
+  GpuMemoryManager( Graphics& graphics );
+
+private:
+
+  class Impl;
+  std::unique_ptr<Impl> mImpl;
+};
+
+}
+
+}
+
+}
+
+#endif //DALI_VULKAN_161117_GPU_MEMORY_MANAGER_H
diff --git a/dali/graphics/vulkan/shaders/basic-shader.frag b/dali/graphics/vulkan/shaders/basic-shader.frag
new file mode 100644 (file)
index 0000000..63e6c1c
--- /dev/null
@@ -0,0 +1,9 @@
+#version 430
+
+layout( location = 0 ) in vec4 triColor;
+layout( location = 0 ) out vec4 outColor;
+
+void main()
+{
+    outColor = triColor;
+}
\ No newline at end of file
diff --git a/dali/graphics/vulkan/shaders/basic-shader.vert b/dali/graphics/vulkan/shaders/basic-shader.vert
new file mode 100644 (file)
index 0000000..6f1988f
--- /dev/null
@@ -0,0 +1,19 @@
+#version 430
+
+layout( location = 0 ) in vec3 aPosition;
+
+layout( set = 0, binding = 0, std140 ) uniform world
+{
+    mat4 modelMat;
+    mat4 viewMat;
+    mat4 projMat;
+    vec4 color;
+};
+
+layout( location = 0 ) out vec4 triColor;
+
+void main()
+{
+    gl_Position = projMat * viewMat * modelMat * vec4( aPosition, 1.0 );
+    triColor = color;
+}
\ No newline at end of file
index 17b4b74..81226da 100644 (file)
@@ -1,5 +1,179 @@
-//
-// Created by adam.b on 06/06/17.
-//
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
 
-#include "vulkan-buffer.h"
+#include <dali/graphics/vulkan/vulkan-buffer.h>
+#include <dali/graphics/vulkan/vulkan-graphics.h>
+#include <dali/graphics/vulkan/gpu-memory/vulkan-gpu-memory-manager.h>
+#include <dali/graphics/vulkan/gpu-memory/vulkan-gpu-memory-handle.h>
+
+namespace Dali
+{
+namespace Graphics
+{
+namespace Vulkan
+{
+
+struct Buffer::Impl final
+{
+  /**
+   *
+   * @param graphics
+   * @param createInfo
+   */
+  Impl(Graphics& graphics, Buffer& owner, const vk::BufferCreateInfo& createInfo)
+  : mGraphics(graphics),
+    mInterface( owner ),
+    mDeviceMemory(nullptr),
+    mInfo(createInfo)
+  {
+  }
+
+  /**
+   *
+   */
+  ~Impl()
+  {
+    mGraphics.GetDevice().destroyBuffer( mBuffer, mGraphics.GetAllocator() );
+  }
+
+  /**
+   * Initialises Buffer with memory, as host visible ( for write )
+   * @return
+   */
+  bool Initialise()
+  {
+    mBuffer = VkAssert(mGraphics.GetDevice().createBuffer( mInfo, mGraphics.GetAllocator()));
+    return true;
+  }
+
+  /**
+   *
+   * @return
+   */
+  vk::BufferUsageFlags GetUsage() const
+  {
+    return mInfo.usage;
+  }
+
+  /**
+   *
+   * @return
+   */
+  size_t GetSize() const
+  {
+    return static_cast<size_t>(mInfo.size);
+  }
+
+  /**
+   *
+   * @return
+   */
+  vk::Buffer GetVkBuffer() const
+  {
+    return mBuffer;
+  }
+
+  void BindMemory( GpuMemoryBlockHandle handle )
+  {
+    assert( mBuffer && "Buffer not initialised!");
+    VkAssert(mGraphics.GetDevice().bindBufferMemory( mBuffer, (*handle), 0 ));
+    mDeviceMemory = handle;
+  }
+
+  Vulkan::Graphics&                     mGraphics;
+  Vulkan::Buffer&                       mInterface;
+  GpuMemoryBlockHandle                  mDeviceMemory;
+  vk::BufferCreateInfo                  mInfo;
+  vk::Buffer                            mBuffer;
+};
+
+/**
+ *
+ * @param graphics
+ * @param size
+ * @return
+ */
+BufferHandle Buffer::New(Graphics& graphics, size_t size, Type type)
+{
+  auto usageFlags = vk::BufferUsageFlags{};
+
+  switch( type )
+  {
+    case Type::VERTEX: { usageFlags |= vk::BufferUsageFlagBits::eVertexBuffer; break; };
+    case Type::INDEX: { usageFlags |= vk::BufferUsageFlagBits::eIndexBuffer; break; };
+    case Type::UNIFORM: { usageFlags |= vk::BufferUsageFlagBits::eUniformBuffer; break; };
+    case Type::SHADER_STORAGE: { usageFlags |= vk::BufferUsageFlagBits::eStorageBuffer; break; };
+  }
+
+  auto info = vk::BufferCreateInfo{};
+  info.setSharingMode( vk::SharingMode::eExclusive );
+  info.setSize( size );
+  info.setUsage( usageFlags | vk::BufferUsageFlagBits::eTransferDst );
+  auto buffer = Handle<Buffer>( new Buffer(graphics, info) );
+
+  if(buffer && buffer->mImpl->Initialise())
+  {
+    graphics.AddBuffer( buffer );
+  }
+  return buffer;
+}
+
+Buffer::Buffer(Graphics& graphics, const vk::BufferCreateInfo& createInfo)
+: VkManaged()
+{
+  mImpl = MakeUnique<Buffer::Impl>(graphics, *this, createInfo);
+}
+
+Buffer::~Buffer() = default;
+
+vk::BufferUsageFlags Buffer::GetUsage() const
+{
+  return mImpl->GetUsage();
+}
+
+const GpuMemoryBlockHandle& Buffer::GetMemoryHandle() const
+{
+  return mImpl->mDeviceMemory;
+}
+
+uint32_t Buffer::GetSize() const
+{
+  return U32(mImpl->GetSize());
+}
+
+vk::Buffer Buffer::GetVkBuffer() const
+{
+  return mImpl->GetVkBuffer();
+}
+
+void Buffer::BindMemory( const GpuMemoryBlockHandle& handle )
+{
+  mImpl->BindMemory( handle );
+}
+
+bool Buffer::OnDestroy()
+{
+  mImpl->mGraphics.RemoveBuffer( *this );
+  return true;
+}
+
+
+}
+
+}
+
+}
\ No newline at end of file
index 5cdedc6..0b67908 100644 (file)
@@ -1,9 +1,22 @@
-//
-// Created by adam.b on 06/06/17.
-//
+#ifndef DALI_GRAPHICS_VULKAN_BUFFER_H
+#define DALI_GRAPHICS_VULKAN_BUFFER_H
 
-#ifndef VULKAN_PROJECT_BUFFER_H
-#define VULKAN_PROJECT_BUFFER_H
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
 
 #include <dali/graphics/vulkan/vulkan-types.h>
 
@@ -13,12 +26,101 @@ namespace Graphics
 {
 namespace Vulkan
 {
+class DeviceMemory;
+class Graphics;
+class GpuMemoryBlock;
+using GpuMemoryBlockHandle = Handle<GpuMemoryBlock>;
 
-class Buffer
+using VertexBuffer = Buffer;
+using UniformBuffer = Buffer;
+using IndexBuffer = Buffer;
+using BufferHandle = Handle<Buffer>;
+
+class Buffer : public VkManaged
 {
+public:
+
+  /**
+   * Type of the buffer
+   */
+  enum class Type
+  {
+    VERTEX,
+    INDEX,
+    UNIFORM,
+    SHADER_STORAGE
+  };
+
+  /**
+   * Destructor
+   */
+  ~Buffer() override;
+
+  /**
+   * Creates logical buffer without allocating any memory
+   * @param graphics
+   * @param size
+   * @param type
+   * @return
+   */
+  static BufferHandle New( Graphics& graphics, size_t size, Type type );
+
+  /**
+   * Returns buffer usage flags
+   * @return
+   */
+  vk::BufferUsageFlags GetUsage() const;
+
+  /**
+   * Returns buffer size in bytes
+   * @return
+   */
+  uint32_t GetSize() const;
+
+  /**
+   * Returns Vulkan VkBuffer object associated with this buffer
+   * @return
+   */
+  vk::Buffer GetVkBuffer() const;
+
+  /**
+   * Returns handle to the allocated memory
+   * @return
+   */
+  const GpuMemoryBlockHandle& GetMemoryHandle() const;
 
+  /**
+   * Binds buffer memory
+   * @param handle
+   */
+  void BindMemory( const GpuMemoryBlockHandle& handle );
+
+public:
+
+  /**
+   *
+   * @return
+   */
+  bool OnDestroy() override;
+
+
+private:
+
+  /**
+   * Creates new VkBuffer with given specification, it doesn't
+   * bind the memory.
+   * @param graphics
+   * @param createInfo
+   */
+  Buffer(Graphics& graphics, const vk::BufferCreateInfo& createInfo);
+
+private:
+
+  class Impl;
+  std::unique_ptr<Buffer::Impl> mImpl;
 };
 
+
 }
 }
 }
index 501cd26..f67dba9 100644 (file)
  */
 
 // INTERNAL INCLUDES
+#include <dali/graphics/vulkan/vulkan-types.h>
 #include <dali/graphics/vulkan/vulkan-command-buffer.h>
 #include <dali/graphics/vulkan/vulkan-command-pool.h>
 #include <dali/graphics/vulkan/vulkan-graphics.h>
+#include <dali/graphics/vulkan/vulkan-buffer.h>
+#include <dali/graphics/vulkan/vulkan-image.h>
+#include <dali/graphics/vulkan/vulkan-pipeline.h>
+#include <dali/graphics/vulkan/vulkan-descriptor-set.h>
+#include <dali/graphics/vulkan/vulkan-surface.h>
 
 namespace Dali
 {
@@ -27,60 +33,380 @@ namespace Graphics
 namespace Vulkan
 {
 
-CommandBuffer::CommandBuffer(Graphics& graphics, CommandPool& ownerPool)
-: CommandBuffer(graphics, ownerPool,
-                vk::CommandBufferAllocateInfo().setCommandBufferCount(1).setLevel(vk::CommandBufferLevel::ePrimary))
+struct CommandBuffer::Impl
 {
-}
+  Impl( CommandPool& commandPool, const vk::CommandBufferAllocateInfo& allocateInfo, vk::CommandBuffer commandBuffer )
+  : mGraphics( commandPool.GetGraphics() ),
+    mOwnerCommandPool( commandPool ),
+    mAllocateInfo( allocateInfo ),
+    mCommandBuffer( commandBuffer )
+  {
+
+  }
+
+  ~Impl()
+  {
+  }
+
+  bool Initialise()
+  {
+    return true;
+  }
+
+  template <class T>
+  bool IsResourceAdded( Handle<T> resourceHandle )
+  {
+    for( auto&& res : mResources )
+    {
+      if( res == resourceHandle )
+      {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  template <class T>
+  bool PushResource( Handle<T> resourceHandle )
+  {
+    if(!IsResourceAdded( resourceHandle ))
+    {
+      mResources.push_back(VkTypeCast<VkManaged>( resourceHandle ));
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   *
+   */
+  void Begin(vk::CommandBufferUsageFlags usageFlags, vk::CommandBufferInheritanceInfo* inheritanceInfo)
+  {
+    assert(!mRecording && "CommandBuffer already is in the recording state");
+    auto info = vk::CommandBufferBeginInfo{};
+    info.setPInheritanceInfo(inheritanceInfo);
+    info.setFlags(usageFlags);
+
+    // set the inheritance option
+    auto inheritance = vk::CommandBufferInheritanceInfo{}.setSubpass( 0 );
+
+    if( mAllocateInfo.level == vk::CommandBufferLevel::eSecondary )
+    {
+      // todo: sets render pass from 'default' surface, should be supplied from primary command buffer
+      // which has render pass associated within execution context
+      inheritance.setRenderPass( mGraphics.GetSurface(0).GetRenderPass() );
+      info.setPInheritanceInfo( &inheritance );
+    }
+
+    VkAssert(mCommandBuffer.begin(info));
+    mRecording = true;
+  }
+
+  void End()
+  {
+    assert(mRecording && "CommandBuffer is not in the recording state!");
+    VkAssert(mCommandBuffer.end());
+    mRecording = false;
+  }
+
+  void Reset()
+  {
+    assert(!mRecording && "Can't reset command buffer during recording!");
+    assert(mCommandBuffer && "Invalid command buffer!");
+    mCommandBuffer.reset(vk::CommandBufferResetFlagBits::eReleaseResources);
+  }
+
+  void Free()
+  {
+    assert(mCommandBuffer && "Invalid command buffer!");
+    mGraphics.GetDevice().freeCommandBuffers(mOwnerCommandPool.GetPool(), mCommandBuffer);
+  }
+
+  void ImageLayoutTransition(vk::Image            image,
+                             vk::ImageLayout      oldLayout,
+                             vk::ImageLayout      newLayout,
+                             vk::ImageAspectFlags aspectMask)
+  {
+    // just push new image barrier until any command is being called or buffer recording ends.
+    // it will make sure we batch barriers together rather than calling cmdPipelineBarrier
+    // for each separately
+    vk::AccessFlags        srcAccessMask, dstAccessMask;
+    vk::PipelineStageFlags srcStageMask, dstStageMask;
+
+    // TODO: add other transitions
+    switch(oldLayout)
+    {
+      case vk::ImageLayout::eUndefined:
+      {
+        srcStageMask = vk::PipelineStageFlagBits::eTopOfPipe;
+      }
+      break;
+      case vk::ImageLayout::ePresentSrcKHR:
+      {
+        srcStageMask = vk::PipelineStageFlagBits::eBottomOfPipe;
+        srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead;
+      }
+      break;
+      case vk::ImageLayout::eColorAttachmentOptimal:
+      {
+        srcStageMask = vk::PipelineStageFlagBits::eFragmentShader | vk::PipelineStageFlagBits::eColorAttachmentOutput;
+        srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead;
+      }
+      break;
+      case vk::ImageLayout::eGeneral:
+      case vk::ImageLayout::eDepthStencilAttachmentOptimal:
+      case vk::ImageLayout::eDepthStencilReadOnlyOptimal:
+      case vk::ImageLayout::eShaderReadOnlyOptimal:
+      case vk::ImageLayout::eTransferSrcOptimal:
+      case vk::ImageLayout::eTransferDstOptimal:
+      case vk::ImageLayout::ePreinitialized:
+      case vk::ImageLayout::eSharedPresentKHR:
+      {
+      }
+      }
+
+      switch(newLayout)
+      {
+      case vk::ImageLayout::eColorAttachmentOptimal:
+      {
+        dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eFragmentShader;
+        dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eHostWrite;
+        break;
+      }
+      case vk::ImageLayout::eDepthStencilAttachmentOptimal:
+      {
+        dstStageMask = vk::PipelineStageFlagBits::eFragmentShader | vk::PipelineStageFlagBits::eEarlyFragmentTests;
+        dstAccessMask = vk::AccessFlagBits::eDepthStencilAttachmentRead | vk::AccessFlagBits::eDepthStencilAttachmentWrite;
+        break;
+      }
+      case vk::ImageLayout::ePresentSrcKHR:
+      {
+        dstStageMask  = vk::PipelineStageFlagBits::eBottomOfPipe;
+        dstAccessMask = vk::AccessFlagBits::eColorAttachmentRead | vk::AccessFlagBits::eMemoryRead;
+      }
+      case vk::ImageLayout::eGeneral:
+      case vk::ImageLayout::eDepthStencilReadOnlyOptimal:
+      case vk::ImageLayout::eShaderReadOnlyOptimal:
+      case vk::ImageLayout::eTransferSrcOptimal:
+      case vk::ImageLayout::eTransferDstOptimal:
+      case vk::ImageLayout::ePreinitialized:
+      case vk::ImageLayout::eUndefined:
+      case vk::ImageLayout::eSharedPresentKHR:
+      {
+        break;
+      }
+
+    }
+
+    RecordImageLayoutTransition(image, srcAccessMask, dstAccessMask, srcStageMask, dstStageMask,
+                                oldLayout, newLayout, aspectMask);
+  }
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wframe-larger-than="
+  void RecordImageLayoutTransition(vk::Image image, vk::AccessFlags srcAccessMask,
+                                   vk::AccessFlags dstAccessMask, vk::PipelineStageFlags srcStageMask,
+                                   vk::PipelineStageFlags dstStageMask, vk::ImageLayout oldLayout,
+                                   vk::ImageLayout newLayout, vk::ImageAspectFlags aspectMask)
+  {
+    vk::ImageSubresourceRange subres;
+    subres.setLayerCount(1).setBaseMipLevel(0).setBaseArrayLayer(0).setLevelCount(1).setAspectMask(aspectMask);
+
+
+    auto barrier = vk::ImageMemoryBarrier{};
+    barrier
+      .setImage(image)
+      .setSubresourceRange(subres)
+      .setSrcAccessMask(srcAccessMask)
+      .setDstAccessMask(dstAccessMask)
+      .setOldLayout(oldLayout)
+      .setNewLayout(newLayout);
+    ;
+    // todo: implement barriers batching
+    mCommandBuffer.pipelineBarrier(srcStageMask, dstStageMask, vk::DependencyFlags{}, nullptr, nullptr, barrier);
+  }
+#pragma GCC diagnostic pop
+
+  /** Push wait semaphores */
+  void PushWaitSemaphores(const std::vector< vk::Semaphore >&          semaphores,
+                          const std::vector< vk::PipelineStageFlags >& stages)
+  {
+    mWaitSemaphores = semaphores;
+    mWaitStages     = stages;
+  }
+
+  /** Push signal semaphores */
+  void PushSignalSemaphores(const std::vector< vk::Semaphore >& semaphores)
+  {
+    mSignalSemaphores = semaphores;
+  }
+
+  // TODO: handles should be synchronized
+  void BindVertexBuffers(uint32_t firstBinding, uint32_t bindingCount, std::vector<Handle<Buffer>> buffers,
+                                        const vk::DeviceSize *pOffsets)
+  {
+    // update list of used resources and create an array of VkBuffers
+    std::vector<vk::Buffer> vkBuffers;
+    vkBuffers.reserve( buffers.size() );
+    for( auto&& buffer : buffers )
+    {
+      vkBuffers.emplace_back( buffer->GetVkBuffer() );
+      PushResource(buffer);
+    }
+
+    mCommandBuffer.bindVertexBuffers( firstBinding, bindingCount, vkBuffers.data(), pOffsets);
+  }
+
+  void BindIndexBuffer( BufferRef buffer, uint32_t offset, vk::IndexType indexType)
+  {
+    // validate
+    assert ( (buffer->GetUsage() & vk::BufferUsageFlagBits::eIndexBuffer) && "The buffer used as index buffer has wrong usage flags!" );
+
+    PushResource( buffer );
+    mCommandBuffer.bindIndexBuffer( buffer->GetVkBuffer(), offset, indexType );
+  }
+
+  void BindGraphicsPipeline( Handle<Pipeline> pipeline )
+  {
+    PushResource( pipeline );
+    mCurrentPipeline = pipeline;
+    mCommandBuffer.bindPipeline( vk::PipelineBindPoint::eGraphics, pipeline->GetVkPipeline() );
+  }
+
+  void BindDescriptorSets( std::vector<Dali::Graphics::Vulkan::Handle<DescriptorSet>> descriptorSets,
+                                          Handle<Pipeline> pipeline, uint32_t firstSet, uint32_t descriptorSetCount )
+  {
+    // update resources
+    PushResource( pipeline );
+    std::vector<vk::DescriptorSet> vkSets;
+    vkSets.reserve( descriptorSets.size() );
+    for( auto&& set : descriptorSets )
+    {
+      vkSets.emplace_back( set->GetVkDescriptorSet() );
+      PushResource( set );
+    }
+
+    // TODO: support dynamic offsets
+    mCommandBuffer.bindDescriptorSets( vk::PipelineBindPoint::eGraphics, pipeline->GetVkPipelineLayout(),
+    firstSet, descriptorSetCount, vkSets.data(), 0, nullptr );
+  }
+
+  void Draw( uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance )
+  {
+    mCommandBuffer.draw( vertexCount, instanceCount, firstVertex, firstInstance );
+  }
+
+  void DrawIndexed( uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, uint32_t vertexOffset, uint32_t firstInstance )
+  {
+    mCommandBuffer.drawIndexed( indexCount, instanceCount, firstIndex, vertexOffset, firstInstance );
+  }
+
+  const std::vector< Handle<VkManaged>> GetResources() const
+  {
+    return mResources;
+  }
+
+  // RENDER PASS
+  void BeginRenderPass( FBID framebufferId, uint32_t bufferIndex )
+  {
+    auto& surface = mGraphics.GetSurface( framebufferId );
+    auto renderPass = surface.GetRenderPass();
+    auto frameBuffer = surface.GetFramebuffer( bufferIndex );
+    auto clearValues = surface.GetClearValues();
+
+    auto info = vk::RenderPassBeginInfo{};
+    info.setFramebuffer( frameBuffer );
+    info.setRenderPass( renderPass );
+    info.setClearValueCount( U32(clearValues.size()) );
+    info.setPClearValues( clearValues.data() );
+    info.setRenderArea( vk::Rect2D( { 0,0 }, surface.GetSize() ) );
+
+    mCurrentRenderPass = renderPass;
+    mCommandBuffer.beginRenderPass( info, vk::SubpassContents::eInline );
+  }
+
+  void BeginRenderPass( vk::RenderPassBeginInfo renderPassBeginInfo, vk::SubpassContents subpassContents )
+  {
+    mCurrentRenderPass = renderPassBeginInfo.renderPass;
+    mCommandBuffer.beginRenderPass( renderPassBeginInfo, subpassContents );
+  }
+
+  void EndRenderPass()
+  {
+    mCurrentRenderPass = nullptr;
+    mCommandBuffer.endRenderPass();
+  }
+
+  void ExecuteCommands( std::vector<Dali::Graphics::Vulkan::Handle<CommandBuffer>> commandBuffers )
+  {
+    auto vkBuffers = std::vector<vk::CommandBuffer>{};
+    vkBuffers.reserve( commandBuffers.size() );
+    for( auto&& buf : commandBuffers )
+    {
+      vkBuffers.emplace_back( buf->GetVkCommandBuffer() );
+      PushResource( buf );
+    }
+
+    mCommandBuffer.executeCommands( vkBuffers );
+  }
+
+  Graphics&                       mGraphics;
+  CommandPool&                    mOwnerCommandPool;
+  vk::CommandBufferAllocateInfo   mAllocateInfo {};
 
-CommandBuffer::CommandBuffer(Graphics& graphics, CommandPool& ownerPool,
-                             const vk::CommandBufferAllocateInfo& allocateInfo)
-: mGraphics(graphics), mCommandPool(ownerPool), mRecording(false)
+  vk::CommandBuffer     mCommandBuffer {};
+
+  // semaphores per command buffer
+  std::vector< vk::Semaphore >          mSignalSemaphores {};
+  std::vector< vk::Semaphore >          mWaitSemaphores {};
+  std::vector< vk::PipelineStageFlags > mWaitStages {};
+
+  std::vector< Handle<VkManaged>> mResources; // used resources
+
+  PipelineRef mCurrentPipeline;
+
+  vk::RenderPass mCurrentRenderPass;
+
+  bool mRecording { false };
+};
+
+/**
+ *
+ * Class: CommandBuffer
+ *
+ */
+
+CommandBuffer::CommandBuffer( CommandPool& commandPool, const vk::CommandBufferAllocateInfo& allocateInfo, vk::CommandBuffer vkCommandBuffer )
 {
-  assert(allocateInfo.commandBufferCount == 1 && "Number of buffers to allocate must be equal 1!");
-  mCommandBuffer = VkAssert(mGraphics.GetDevice().allocateCommandBuffers(allocateInfo))[0];
+  mImpl = MakeUnique<Impl>( commandPool, allocateInfo, vkCommandBuffer );
 }
 
 CommandBuffer::~CommandBuffer()
 {
-  if(mCommandBuffer)
-  {
-    mGraphics.GetDevice().freeCommandBuffers(mCommandPool.GetPool(), mCommandBuffer);
-  }
 }
 
 /** Begin recording */
 void CommandBuffer::Begin(vk::CommandBufferUsageFlags usageFlags, vk::CommandBufferInheritanceInfo* inheritanceInfo)
 {
-  assert(!mRecording && "CommandBuffer already is in the recording state");
-  auto info = vk::CommandBufferBeginInfo{};
-  info.setPInheritanceInfo(inheritanceInfo);
-  info.setFlags(usageFlags);
-  VkAssert(mCommandBuffer.begin(info));
-  mRecording = true;
+  mImpl->Begin( usageFlags, inheritanceInfo );
 }
 
 /** Finish recording */
 void CommandBuffer::End()
 {
-  assert(mRecording && "CommandBuffer is not in the recording state!");
-  VkAssert(mCommandBuffer.end());
-  mRecording = false;
+  mImpl->End();
 }
 
 /** Reset command buffer */
 void CommandBuffer::Reset()
 {
-  assert(!mRecording && "Can't reset command buffer during recording!");
-  assert(mCommandBuffer && "Invalid command buffer!");
-  mCommandBuffer.reset(vk::CommandBufferResetFlagBits::eReleaseResources);
+  mImpl->Reset();
 }
 
 /** Free command buffer */
 void CommandBuffer::Free()
 {
-  assert(mCommandBuffer && "Invalid command buffer!");
-  mGraphics.GetDevice().freeCommandBuffers(mCommandPool.GetPool(), mCommandBuffer);
+  mImpl->Free();
 }
 
 /** Records image layout transition barrier for one image */
@@ -89,119 +415,115 @@ void CommandBuffer::ImageLayoutTransition(vk::Image            image,
                                           vk::ImageLayout      newLayout,
                                           vk::ImageAspectFlags aspectMask)
 {
-  // must be in recording state
-
-  // just push new image barrier until any command is being called or buffer recording ends.
-  // it will make sure we batch barriers together rather than calling cmdPipelineBarrier
-  // for each separately
-  vk::AccessFlags        srcAccessMask, dstAccessMask;
-  vk::PipelineStageFlags srcStageMask, dstStageMask;
-
-  // TODO: add other transitions
-  switch(oldLayout)
-  {
-  case vk::ImageLayout::eUndefined:
-  {
-    srcStageMask = vk::PipelineStageFlagBits::eTopOfPipe;
-  }
-  break;
-  case vk::ImageLayout::ePresentSrcKHR:
-  {
-    srcStageMask = vk::PipelineStageFlagBits::eBottomOfPipe;
-    srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead;
-  }
-  break;
-  case vk::ImageLayout::eColorAttachmentOptimal:
-  {
-    srcStageMask = vk::PipelineStageFlagBits::eFragmentShader | vk::PipelineStageFlagBits::eColorAttachmentOutput;
-    srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead;
-  }
-  break;
-  case vk::ImageLayout::eGeneral:
-  case vk::ImageLayout::eDepthStencilAttachmentOptimal:
-  case vk::ImageLayout::eDepthStencilReadOnlyOptimal:
-  case vk::ImageLayout::eShaderReadOnlyOptimal:
-  case vk::ImageLayout::eTransferSrcOptimal:
-  case vk::ImageLayout::eTransferDstOptimal:
-  case vk::ImageLayout::ePreinitialized:
-  case vk::ImageLayout::eSharedPresentKHR:
-  {
-  }
-  }
-
-  switch(newLayout)
-  {
-  case vk::ImageLayout::eColorAttachmentOptimal:
-  {
-    dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eFragmentShader;
-    dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eHostWrite;
-    break;
-  }
-  case vk::ImageLayout::eDepthStencilAttachmentOptimal:
-  {
-    dstStageMask = vk::PipelineStageFlagBits::eFragmentShader | vk::PipelineStageFlagBits::eEarlyFragmentTests;
-    dstAccessMask = vk::AccessFlagBits::eDepthStencilAttachmentRead | vk::AccessFlagBits::eDepthStencilAttachmentWrite;
-    break;
-  }
-  case vk::ImageLayout::ePresentSrcKHR:
-  {
-    dstStageMask  = vk::PipelineStageFlagBits::eBottomOfPipe;
-    dstAccessMask = vk::AccessFlagBits::eColorAttachmentRead | vk::AccessFlagBits::eMemoryRead;
-  }
-  case vk::ImageLayout::eGeneral:
-  case vk::ImageLayout::eDepthStencilReadOnlyOptimal:
-  case vk::ImageLayout::eShaderReadOnlyOptimal:
-  case vk::ImageLayout::eTransferSrcOptimal:
-  case vk::ImageLayout::eTransferDstOptimal:
-  case vk::ImageLayout::ePreinitialized:
-  case vk::ImageLayout::eUndefined:
-  case vk::ImageLayout::eSharedPresentKHR:
-  default:
-  {
-  }
-  }
-
-  RecordImageLayoutTransition(image, srcAccessMask, dstAccessMask, srcStageMask, dstStageMask,
-                              oldLayout, newLayout, aspectMask);
+  mImpl->ImageLayoutTransition( image, oldLayout, newLayout, aspectMask );
 }
 
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wframe-larger-than="
 void CommandBuffer::RecordImageLayoutTransition(vk::Image image, vk::AccessFlags srcAccessMask,
                                                 vk::AccessFlags dstAccessMask, vk::PipelineStageFlags srcStageMask,
                                                 vk::PipelineStageFlags dstStageMask, vk::ImageLayout oldLayout,
                                                 vk::ImageLayout newLayout, vk::ImageAspectFlags aspectMask)
 {
-  vk::ImageSubresourceRange subres;
-  subres.setLayerCount(1).setBaseMipLevel(0).setBaseArrayLayer(0).setLevelCount(1).setAspectMask(aspectMask);
-
-
-  auto barrier = vk::ImageMemoryBarrier{};
-  barrier
-                     .setImage(image)
-                     .setSubresourceRange(subres)
-                     .setSrcAccessMask(srcAccessMask)
-                     .setDstAccessMask(dstAccessMask)
-                     .setOldLayout(oldLayout)
-                     .setNewLayout(newLayout);
-  ;
-  // todo: implement barriers batching
-  mCommandBuffer.pipelineBarrier(srcStageMask, dstStageMask, vk::DependencyFlags{}, nullptr, nullptr, barrier);
+  mImpl->RecordImageLayoutTransition( image, srcAccessMask, dstAccessMask,srcStageMask, dstStageMask, oldLayout, newLayout, aspectMask );
 }
-#pragma GCC diagnostic pop
 
 /** Push wait semaphores */
 void CommandBuffer::PushWaitSemaphores(const std::vector< vk::Semaphore >&          semaphores,
                                        const std::vector< vk::PipelineStageFlags >& stages)
 {
-  mWaitSemaphores = semaphores;
-  mWaitStages     = stages;
+  mImpl->PushWaitSemaphores( semaphores, stages );
 }
 
 /** Push signal semaphores */
 void CommandBuffer::PushSignalSemaphores(const std::vector< vk::Semaphore >& semaphores)
 {
-  mSignalSemaphores = semaphores;
+  mImpl->PushSignalSemaphores( semaphores );
+}
+
+const std::vector< vk::Semaphore >& CommandBuffer::GetSignalSemaphores() const
+{
+  return mImpl->mSignalSemaphores;
+}
+
+const std::vector< vk::Semaphore >& CommandBuffer::GetSWaitSemaphores() const
+{
+  return mImpl->mWaitSemaphores;
+}
+
+const std::vector< vk::PipelineStageFlags >& CommandBuffer::GetWaitSemaphoreStages() const
+{
+  return mImpl->mWaitStages;
+}
+
+vk::CommandBuffer CommandBuffer::GetVkCommandBuffer() const
+{
+  return mImpl->mCommandBuffer;
+}
+
+bool CommandBuffer::IsPrimary() const
+{
+  return mImpl->mAllocateInfo.level == vk::CommandBufferLevel::ePrimary;
+}
+
+void CommandBuffer::BindVertexBuffers(uint32_t firstBinding, uint32_t bindingCount, std::vector<Handle<Buffer>> buffers,
+                       const vk::DeviceSize *pOffsets)
+{
+  mImpl->BindVertexBuffers( firstBinding, bindingCount, buffers, pOffsets );
+}
+
+void CommandBuffer::BindIndexBuffer( BufferRef buffer, uint32_t offset, vk::IndexType indexType)
+{
+  mImpl->BindIndexBuffer( buffer, offset, indexType );
+}
+
+void CommandBuffer::BindVertexBuffer(uint32_t binding, Dali::Graphics::Vulkan::Handle<Buffer> buffer, vk::DeviceSize offset )
+{
+  mImpl->BindVertexBuffers( binding, 1, std::vector<Handle<Buffer>>({ buffer }), &offset );
+}
+
+void CommandBuffer::BindGraphicsPipeline( Handle<Pipeline> pipeline )
+{
+  mImpl->BindGraphicsPipeline( pipeline );
+}
+
+void CommandBuffer::BindDescriptorSets( std::vector<Dali::Graphics::Vulkan::Handle<DescriptorSet>> descriptorSets,
+                         Handle<Pipeline> pipeline, uint32_t firstSet, uint32_t descriptorSetCount )
+{
+  mImpl->BindDescriptorSets( descriptorSets, pipeline, firstSet, descriptorSetCount );
+}
+
+void CommandBuffer::BindDescriptorSets( std::vector<Dali::Graphics::Vulkan::Handle<DescriptorSet>> descriptorSets, uint32_t firstSet )
+{
+  mImpl->BindDescriptorSets( descriptorSets, mImpl->mCurrentPipeline, 0, static_cast<uint32_t>(descriptorSets.size()) );
+}
+
+void CommandBuffer::Draw( uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance )
+{
+  mImpl->Draw( vertexCount, instanceCount, firstVertex, firstInstance );
+}
+
+void CommandBuffer::DrawIndexed( uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, uint32_t vertexOffset, uint32_t firstInstance )
+{
+  mImpl->DrawIndexed( indexCount, instanceCount, firstIndex, vertexOffset, firstInstance );
+}
+
+void CommandBuffer::BeginRenderPass( FBID framebufferId, uint32_t bufferIndex )
+{
+  mImpl->BeginRenderPass( framebufferId, bufferIndex );
+}
+
+void CommandBuffer::BeginRenderPass( vk::RenderPassBeginInfo renderPassBeginInfo, vk::SubpassContents subpassContents )
+{
+  mImpl->BeginRenderPass( renderPassBeginInfo, subpassContents );
+}
+
+void CommandBuffer::EndRenderPass()
+{
+  mImpl->EndRenderPass();
+}
+
+void CommandBuffer::ExecuteCommands( std::vector<Dali::Graphics::Vulkan::Handle<CommandBuffer>> commandBuffers )
+{
+  mImpl->ExecuteCommands( commandBuffers );
 }
 
 } // namespace Vulkan
index 3fb0675..2dab9f7 100644 (file)
@@ -27,19 +27,20 @@ namespace Graphics
 {
 namespace Vulkan
 {
-
+class Image;
 class Graphics;
-class CommandPool;
-class CommandBuffer
+class Buffer;
+class Pipeline;
+class DescriptorSet;
+class CommandBuffer : public VkManaged
 {
+  friend class CommandPool;
+
 public:
-  CommandBuffer() = delete;
 
-  CommandBuffer(Graphics& graphics, CommandPool& ownerPool, vk::CommandBuffer commandBuffer);
-  CommandBuffer(Graphics& graphics, CommandPool& ownerPool, const vk::CommandBufferAllocateInfo& allocateInfo);
-  CommandBuffer(Graphics& graphics, CommandPool& ownerPool);
+  CommandBuffer() = delete;
 
-  ~CommandBuffer();
+  ~CommandBuffer() override;
 
   /** Begin recording */
   void Begin(vk::CommandBufferUsageFlags       usageFlags      = vk::CommandBufferUsageFlags{},
@@ -64,28 +65,146 @@ public:
   /** Push signal semaphores */
   void PushSignalSemaphores(const std::vector< vk::Semaphore >& semaphores);
 
-  const std::vector< vk::Semaphore >& GetSignalSemaphores() const
-  {
-    return mSignalSemaphores;
-  }
+  /**
+   *
+   * @return
+   */
+  const std::vector< vk::Semaphore >& GetSignalSemaphores() const;
 
-  const std::vector< vk::Semaphore >& GetSWaitSemaphores() const
-  {
-    return mWaitSemaphores;
-  }
+  /**
+   *
+   * @return
+   */
+  const std::vector< vk::Semaphore >& GetSWaitSemaphores() const;
 
-  const std::vector< vk::PipelineStageFlags >& GetWaitSemaphoreStages() const
-  {
-    return mWaitStages;
-  }
+  /**
+   *
+   * @return
+   */
+  const std::vector< vk::PipelineStageFlags >& GetWaitSemaphoreStages() const;
 
   /** Returns Vulkan object associated with the buffer */
-  inline const vk::CommandBuffer& Get() const
+  vk::CommandBuffer GetVkCommandBuffer() const;
+
+  operator vk::CommandBuffer() const
   {
-    return mCommandBuffer;
+    return GetVkCommandBuffer();
   }
 
+  /**
+   * Tests if the command buffer is primary
+   * @return Returns true if the command buffer is primary
+   */
+  bool IsPrimary() const;
+
+  /**
+   * Binds an array of vertex buffers
+   * @param firstBinding
+   * @param bindingCount
+   * @param buffers
+   * @param pOffsets
+   */
+  void BindVertexBuffers(uint32_t firstBinding, uint32_t bindingCount,
+                         std::vector<Dali::Graphics::Vulkan::Handle<Buffer>> buffers,
+                         const vk::DeviceSize *pOffsets);
+
+  /**
+   * Binds an index buffer
+   * @param buffer
+   * @param offset
+   * @param indexType
+   */
+  void BindIndexBuffer( BufferRef buffer, uint32_t offset, vk::IndexType indexType);
+
+  /**
+   * Binds single vertex buffer
+   * @param binding
+   * @param buffer
+   * @param offset
+   */
+  void BindVertexBuffer(uint32_t binding, Dali::Graphics::Vulkan::Handle<Buffer> buffer, vk::DeviceSize offset );
+
+  /**
+   * Binds graphics pipeline
+   * @param pipeline
+   */
+  void BindGraphicsPipeline( Handle<Pipeline> pipeline );
+
+  /**
+   *
+   * @param descriptorSets
+   * @param pipeline
+   * @param firstSet
+   * @param descriptorSetCount
+   */
+  void BindDescriptorSets( std::vector<Dali::Graphics::Vulkan::Handle<DescriptorSet>> descriptorSets,
+                           Handle<Pipeline> pipeline, uint32_t firstSet, uint32_t descriptorSetCount );
+
+  /**
+   * Binds descriptor sets to the most recently bound Pipeline
+   * @param descriptorSets
+   * @param firstSet
+   */
+  void BindDescriptorSets( std::vector<Dali::Graphics::Vulkan::Handle<DescriptorSet>> descriptorSets, uint32_t firstSet );
+
+  /**
+   * Issues draw command
+   * @param vertexCount
+   * @param instanceCount
+   * @param firstVertex
+   * @param firstInstance
+   */
+  void Draw( uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance );
+
+  /**
+   * Issues draw indexed primiteve command
+   * @param indexCount
+   * @param instanceCount
+   * @param firstIndex
+   * @param vertexOffset
+   * @param firstInstance
+   */
+  void DrawIndexed( uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, uint32_t vertexOffset, uint32_t firstInstance );
+
+  /**
+   * Begins render pass using VkRenderPass and VkFramebuffer associated with FBID
+   * @todo should be replaced with proper implementation and use the framebuffer
+   * @param framebufferId
+   * @param bufferIndex
+   */
+  void BeginRenderPass( FBID framebufferId, uint32_t bufferIndex );
+
+  /**
+   * Allows to issue custom VkRenderPassBeginInfo structure
+   * @param renderPassBeginInfo
+   * @param subpassContents
+   */
+  void BeginRenderPass( vk::RenderPassBeginInfo renderPassBeginInfo, vk::SubpassContents subpassContents );
+
+  /**
+   * Ends current render pass
+   */
+  void EndRenderPass();
+
+  /**
+   * Executes secondary command buffers within primary command buffer
+   * @param commandBuffers
+   */
+  void ExecuteCommands( std::vector<Dali::Graphics::Vulkan::Handle<CommandBuffer>> commandBuffers );
+
 private:
+
+  /**
+   *
+   * @param image
+   * @param srcAccessMask
+   * @param dstAccessMask
+   * @param srcStageMask
+   * @param dstStageMask
+   * @param oldLayout
+   * @param newLayout
+   * @param aspectMask
+   */
   void RecordImageLayoutTransition(vk::Image             image,
                                    vk::AccessFlags        srcAccessMask,
                                    vk::AccessFlags        dstAccessMask,
@@ -96,18 +215,13 @@ private:
                                    vk::ImageAspectFlags   aspectMask);
 
 private:
-  Graphics& mGraphics;
-
-  CommandPool& mCommandPool;
 
-  // semaphores per command buffer
-  std::vector< vk::Semaphore >          mSignalSemaphores;
-  std::vector< vk::Semaphore >          mWaitSemaphores;
-  std::vector< vk::PipelineStageFlags > mWaitStages;
+  // Constructor called by the CommandPool only
+  CommandBuffer( CommandPool& commandPool, const vk::CommandBufferAllocateInfo& allocateInfo, vk::CommandBuffer vkCommandBuffer );
 
-  vk::CommandBuffer mCommandBuffer;
+  class Impl;
+  std::unique_ptr<Impl> mImpl;
 
-  bool mRecording;
 };
 
 } // namespace Vulkan
index dec4825..7b5de98 100644 (file)
@@ -16,9 +16,9 @@
  */
 
 // INTERNAL INCLUDES
+#include <dali/graphics/vulkan/vulkan-graphics.h>
 #include <dali/graphics/vulkan/vulkan-command-pool.h>
 #include <dali/graphics/vulkan/vulkan-command-buffer.h>
-#include <dali/graphics/vulkan/vulkan-graphics.h>
 
 namespace Dali
 {
@@ -27,41 +27,111 @@ namespace Graphics
 namespace Vulkan
 {
 
-CommandPool::CommandPool(Graphics& graphics, const vk::CommandPoolCreateInfo& createInfo)
-: mGraphics(graphics)
+/**
+ *
+ * Class: CommandPool::Impl
+ */
+
+struct CommandPool::Impl
 {
-  mPool = VkAssert(graphics.GetDevice().createCommandPool(createInfo, graphics.GetAllocator()));
-}
+  Impl( Graphics& graphics, CommandPool& interface, const vk::CommandPoolCreateInfo& createInfo )
+  : mGraphics( graphics ),
+    mInterface( interface ),
+    mCreateInfo( createInfo ),
+    mCommandPool( nullptr )
+  {
+  }
+
+  ~Impl()
+  {
+    if(mCommandPool)
+    {
+      mGraphics.GetDevice().destroyCommandPool( mCommandPool, mGraphics.GetAllocator());
+    }
+  }
+
+  bool Initialise()
+  {
+    mCommandPool = VkAssert(mGraphics.GetDevice().createCommandPool(mCreateInfo, mGraphics.GetAllocator()));
+    return true;
+  }
+
+  Handle<CommandBuffer> NewCommandBuffer( const vk::CommandBufferAllocateInfo& allocateInfo )
+  {
+    vk::CommandBufferAllocateInfo info( allocateInfo );
+    info.setCommandPool( mCommandPool );
+    info.setCommandBufferCount(1);
+    auto retval = VkAssert( mGraphics.GetDevice().allocateCommandBuffers( info ) );
+    mAllocatedCommandBuffers.emplace_back( new CommandBuffer( mInterface, info, retval[0]) );
+    return mAllocatedCommandBuffers.back();
+  }
+
+  Graphics& mGraphics;
+  CommandPool& mInterface;
+  vk::CommandPoolCreateInfo mCreateInfo;
+  vk::CommandPool mCommandPool;
+
+  std::vector<Handle<CommandBuffer>> mAllocatedCommandBuffers;
+};
 
-CommandPool::~CommandPool()
+/**
+ *
+ * Class: CommandPool
+ */
+CommandPoolHandle CommandPool::New( Graphics& graphics, const vk::CommandPoolCreateInfo& createInfo )
 {
-  if(mPool)
+  auto retval = Handle<CommandPool>( new CommandPool(graphics, createInfo) );
+
+  if(retval && retval->mImpl->Initialise())
   {
-    mGraphics.GetDevice().destroyCommandPool(mPool, mGraphics.GetAllocator());
+    graphics.AddCommandPool( retval );
   }
+
+  return retval;
 }
 
-std::unique_ptr< CommandBuffer > CommandPool::AllocateCommandBuffer(
-    const vk::CommandBufferAllocateInfo& info)
+CommandPoolHandle CommandPool::New( Graphics& graphics )
 {
-  auto copyInfo = info;
-  copyInfo.setCommandPool(mPool);
-  return MakeUnique<CommandBuffer>(mGraphics, *this, copyInfo);
+  return New( graphics, vk::CommandPoolCreateInfo{});
 }
 
-std::unique_ptr< CommandBuffer > CommandPool::AllocateCommandBuffer(vk::CommandBufferLevel level)
+CommandPool::CommandPool() = default;
+
+CommandPool::CommandPool(Graphics& graphics, const vk::CommandPoolCreateInfo& createInfo)
 {
-  auto info =
-      vk::CommandBufferAllocateInfo{}.setCommandBufferCount(1).setLevel(level).setCommandPool(
-          mPool);
-  return MakeUnique<CommandBuffer>(mGraphics, *this, info);
+  mImpl = MakeUnique<Impl>( graphics, *this, createInfo );
 }
 
+CommandPool::~CommandPool() = default;
+
 vk::CommandPool CommandPool::GetPool() const
 {
-  return mPool;
+  return mImpl->mCommandPool;
+}
+
+Graphics& CommandPool::GetGraphics() const
+{
+  return mImpl->mGraphics;
 }
 
+bool CommandPool::OnDestroy()
+{
+  return false;
+}
+
+Handle<CommandBuffer> CommandPool::NewCommandBuffer( const vk::CommandBufferAllocateInfo& allocateInfo )
+{
+  return mImpl->NewCommandBuffer( allocateInfo );
+}
+
+Handle<CommandBuffer> CommandPool::NewCommandBuffer( bool isPrimary )
+{
+  return mImpl->NewCommandBuffer( vk::CommandBufferAllocateInfo{}.setLevel(
+    isPrimary ? vk::CommandBufferLevel::ePrimary : vk::CommandBufferLevel::eSecondary
+  ) );
+}
+
+
 } // namespace Vulkan
 } // namespace Graphics
 } // namespace Dali
index 3b227db..e04ec44 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef DALI_GRAPHICS_VULKAN_COMMANDPOOL_H
-#define DALI_GRAPHICS_VULKAN_COMMANDPOOL_H
+#ifndef DALI_GRAPHICS_VULKAN_COMMANDPOOL
+#define DALI_GRAPHICS_VULKAN_COMMANDPOOL
 
 /*
  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
@@ -30,26 +30,75 @@ namespace Vulkan
 
 class Graphics;
 class CommandBuffer;
-class CommandPool
+
+using CommandPoolHandle = Handle<class CommandPool>;
+
+class CommandPool : public VkManaged
 {
+
 public:
 
-  CommandPool( Graphics& graphics, const vk::CommandPoolCreateInfo& createInfo );
-  ~CommandPool();
+  /**
+   *
+   * @param graphics
+   * @param createInfo
+   * @return
+   */
+  static CommandPoolHandle New( Graphics& graphics, const vk::CommandPoolCreateInfo& createInfo );
 
-  std::unique_ptr<CommandBuffer> AllocateCommandBuffer( const vk::CommandBufferAllocateInfo& info );
+  /**
+   *
+   * @param graphics
+   * @return
+   */
+  static CommandPoolHandle New( Graphics& graphics );
 
-  std::unique_ptr<CommandBuffer> AllocateCommandBuffer( vk::CommandBufferLevel level );
+  ~CommandPool() override;
 
+  /**
+   *
+   * @return
+   */
   vk::CommandPool GetPool() const;
 
+  /**
+   *
+   * @return
+   */
+  Graphics& GetGraphics() const;
+
+  /**
+   *
+   * @param allocateInfo
+   * @return
+   */
+  Handle<CommandBuffer> NewCommandBuffer( const vk::CommandBufferAllocateInfo& allocateInfo );
+
+  /**
+   *
+   * @param isPrimary
+   * @return
+   */
+  Handle<CommandBuffer> NewCommandBuffer( bool isPrimary = true );
+
+public:
+
+  bool OnDestroy() override;
+
 private:
-  Graphics&       mGraphics;
-  vk::CommandPool mPool;
+
+  CommandPool();
+
+  CommandPool( Graphics& graphics, const vk::CommandPoolCreateInfo& createInfo );
+
+  class Impl;
+  std::unique_ptr<Impl> mImpl;
+
 };
 
+
 } // namespace Vulkan
 } // namespace Graphics
 } // namespace Dali
 
-#endif // DALI_GRAPHICS_VULKAN_COMMANDPOOL_H
+#endif // DALI_GRAPHICS_VULKAN_COMMANDPOOL
diff --git a/dali/graphics/vulkan/vulkan-descriptor-set.cpp b/dali/graphics/vulkan/vulkan-descriptor-set.cpp
new file mode 100644 (file)
index 0000000..65a56f9
--- /dev/null
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali/graphics/vulkan/vulkan-descriptor-set.h>
+#include <dali/graphics/vulkan/vulkan-graphics.h>
+#include <dali/graphics/vulkan/vulkan-buffer.h>
+#include <dali/graphics/vulkan/vulkan-image.h>
+
+namespace Dali
+{
+namespace Graphics
+{
+namespace Vulkan
+{
+struct DescriptorPool::Impl
+{
+  Impl( DescriptorPool& owner, Graphics& graphics, vk::DescriptorPoolCreateInfo createInfo )
+  : mGraphics( graphics ),
+    mOwner( owner ),
+    mCreateInfo( createInfo )
+  {
+
+  }
+
+  ~Impl()
+  {
+
+  }
+
+  /**
+   * Allocates an array of descriptor sets
+   * @param allocateInfo
+   * @return
+   */
+  std::vector<Handle<DescriptorSet>> AllocateDescriptorSets( vk::DescriptorSetAllocateInfo allocateInfo )
+  {
+    // all other fields must be set correct
+    allocateInfo.setDescriptorPool( mVkDescriptorPool );
+    auto result = VkAssert( mGraphics.GetDevice().allocateDescriptorSets( allocateInfo ) );
+
+    std::vector<Handle<DescriptorSet>> retval;
+    retval.reserve( result.size() );
+    for( auto&& item : result )
+    {
+      Handle<DescriptorSet> handle( new DescriptorSet(mGraphics, mOwner, item, allocateInfo) );
+      retval.emplace_back( handle );
+      mDescriptorSetCache.emplace_back( handle );
+    }
+
+    return retval;
+  }
+
+  bool Initialise()
+  {
+    mVkDescriptorPool = VkAssert( mGraphics.GetDevice().createDescriptorPool( mCreateInfo, mGraphics.GetAllocator() ) );
+    return true;
+  }
+
+  Graphics& mGraphics;
+  DescriptorPool& mOwner;
+  vk::DescriptorPoolCreateInfo mCreateInfo;
+
+  vk::DescriptorPool mVkDescriptorPool;
+
+  // cache
+  std::vector<Handle<DescriptorSet>> mDescriptorSetCache;
+};
+
+Handle<DescriptorPool> DescriptorPool::New( Graphics& graphics, const vk::DescriptorPoolCreateInfo& createInfo )
+{
+  auto pool = Handle<DescriptorPool>( new DescriptorPool( graphics, createInfo ) );
+  if(pool->mImpl->Initialise())
+  {
+    graphics.AddDescriptorPool(pool);
+  }
+  return pool;
+}
+
+DescriptorPool::DescriptorPool( Graphics& graphics, const vk::DescriptorPoolCreateInfo& createInfo )
+{
+  mImpl = MakeUnique<Impl>( *this, graphics, createInfo );
+}
+
+DescriptorPool::~DescriptorPool() = default;
+
+vk::DescriptorPool DescriptorPool::GetVkDescriptorPool() const
+{
+  return mImpl->mVkDescriptorPool;
+}
+
+std::vector<DescriptorSetHandle> DescriptorPool::AllocateDescriptorSets( vk::DescriptorSetAllocateInfo allocateInfo )
+{
+  return mImpl->AllocateDescriptorSets( allocateInfo );
+}
+
+/****************************************************************************************
+ * Class DescriptorSet::Impl
+ */
+
+struct DescriptorSet::Impl
+{
+  Impl( Graphics& graphics, DescriptorPool& pool, vk::DescriptorSet set, vk::DescriptorSetAllocateInfo allocateInfo )
+  : mGraphics( graphics ),
+    mPool( pool ),
+    mAllocateInfo( allocateInfo ),
+    mVkDescriptorSet( set )
+  {
+
+  }
+
+  ~Impl()
+  {
+    if(mVkDescriptorSet)
+    {
+      mGraphics.GetDevice().freeDescriptorSets( mPool.GetVkDescriptorPool(), 1, &mVkDescriptorSet );
+    }
+  }
+
+  void WriteUniformBuffer( uint32_t binding, Handle<Buffer> buffer, uint32_t offset, uint32_t size )
+  {
+    // add resource to the list
+    mResources.emplace_back( buffer.StaticCast<VkManaged>() );
+
+    auto bufferInfo = vk::DescriptorBufferInfo{}
+         .setOffset( U32(offset) )
+         .setRange( U32(size) )
+         .setBuffer( buffer->GetVkBuffer() );
+
+    auto write = vk::WriteDescriptorSet{}.setPBufferInfo( &bufferInfo )
+         .setDescriptorType( vk::DescriptorType::eUniformBuffer )
+         .setDescriptorCount( 1 )
+         .setDstSet( mVkDescriptorSet )
+         .setDstBinding( binding )
+         .setDstArrayElement( 0 );
+
+    // write descriptor set
+    mGraphics.GetDevice().updateDescriptorSets( 1, &write, 0, nullptr  );
+  }
+
+  void WriteStorageBuffer( Handle<Buffer> buffer, uint32_t offset, uint32_t size )
+  {
+    mResources.emplace_back( buffer.StaticCast<VkManaged>() );
+  }
+
+  Graphics& mGraphics;
+  DescriptorPool& mPool;
+  vk::DescriptorSetAllocateInfo mAllocateInfo;
+  vk::DescriptorSet             mVkDescriptorSet;
+
+  // attached resources
+  std::vector<Handle<VkManaged>> mResources;
+};
+
+/**
+ * Called by DescriptorPool only!
+ */
+DescriptorSet::DescriptorSet( Graphics& graphics, DescriptorPool& pool, vk::DescriptorSet descriptorSet, vk::DescriptorSetAllocateInfo allocateInfo )
+{
+  mImpl = MakeUnique<Impl>( graphics, pool, descriptorSet, allocateInfo );
+}
+
+DescriptorSet::~DescriptorSet() = default;
+
+void DescriptorSet::WriteUniformBuffer( uint32_t binding, Handle<Buffer> buffer, uint32_t offset, uint32_t size )
+{
+  mImpl->WriteUniformBuffer( binding, buffer, offset, size );
+}
+
+vk::DescriptorSet DescriptorSet::GetVkDescriptorSet() const
+{
+  return mImpl->mVkDescriptorSet;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+struct DescriptorSetLayout::Impl
+{
+  Impl( Graphics& graphics, const vk::DescriptorSetLayoutCreateInfo& createInfo ) :
+    mGraphics( graphics ),
+    mCreateInfo( createInfo )
+  {
+  }
+
+  ~Impl()
+  {
+    if(mLayout)
+    {
+      mGraphics.GetDevice().destroyDescriptorSetLayout( mLayout, mGraphics.GetAllocator() );
+    }
+  }
+
+  bool Initialise()
+  {
+    mLayout = VkAssert( mGraphics.GetDevice().createDescriptorSetLayout( mCreateInfo, mGraphics.GetAllocator() ));
+    if(mLayout)
+    {
+      return true;
+    }
+    return false;
+  }
+
+  Graphics&                         mGraphics;
+  vk::DescriptorSetLayout           mLayout;
+  vk::DescriptorSetLayoutCreateInfo mCreateInfo;
+};
+
+/**
+ * Class: DescriptorSetLayout
+ */
+
+std::unique_ptr<DescriptorSetLayout> DescriptorSetLayout::New( Graphics& graphics, const vk::DescriptorSetLayoutCreateInfo& createInfo )
+{
+  auto retval = std::unique_ptr<DescriptorSetLayout>( new DescriptorSetLayout(graphics, createInfo ) );
+  if( retval->mImpl->Initialise() )
+  {
+    return retval;
+  }
+  return nullptr;
+}
+
+DescriptorSetLayout::DescriptorSetLayout( Graphics& graphics, const vk::DescriptorSetLayoutCreateInfo& createInfo )
+{
+  mImpl = MakeUnique<DescriptorSetLayout::Impl>( graphics, createInfo );
+}
+
+} // Namespace Vulkan
+
+} // Namespace Graphics
+
+} // Namespace Dali
diff --git a/dali/graphics/vulkan/vulkan-descriptor-set.h b/dali/graphics/vulkan/vulkan-descriptor-set.h
new file mode 100644 (file)
index 0000000..e2d48e9
--- /dev/null
@@ -0,0 +1,128 @@
+#ifndef DALI_GRAPHICS_VULKAN_DESCRIPTOR_SET
+#define DALI_GRAPHICS_VULKAN_DESCRIPTOR_SET
+
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali/graphics/vulkan/vulkan-types.h>
+
+namespace Dali
+{
+namespace Graphics
+{
+namespace Vulkan
+{
+class Graphics;
+class Buffer;
+class Image;
+class DescriptorPool;
+
+class DescriptorSet : public VkManaged
+{
+  friend class DescriptorPool;
+
+public:
+
+  ~DescriptorSet() override;
+
+  /**
+   *
+   * @param buffer
+   * @param offset
+   * @param size
+   */
+  void WriteUniformBuffer( uint32_t binding, Handle<Buffer> buffer, uint32_t offset, uint32_t size );
+
+  /**
+   *
+   * @param buffer
+   * @param offset
+   * @param size
+   */
+  void WriteStorageBuffer( Handle<Buffer> buffer, uint32_t offset, uint32_t size );
+
+  /**
+   *
+   */
+  void WriteImage( Handle<Image> );
+
+  /**
+   *
+   * @param writeDescriptorSet
+   */
+  void Write( vk::WriteDescriptorSet writeDescriptorSet );
+
+  /**
+   * Returns VkDescriptorSet associated with this object
+   * @return Descriptor set
+   */
+  vk::DescriptorSet GetVkDescriptorSet() const;
+
+private:
+
+  DescriptorSet( Graphics& graphics, DescriptorPool& pool, vk::DescriptorSet descriptorSet, vk::DescriptorSetAllocateInfo allocateInfo );
+
+  class Impl;
+  std::unique_ptr<Impl> mImpl;
+};
+
+using DescriptorSetHandle = Handle<DescriptorSet>;
+
+class DescriptorPool : public VkManaged
+{
+public:
+
+  static Handle<DescriptorPool> New( Graphics& graphics, const vk::DescriptorPoolCreateInfo& createInfo );
+
+  ~DescriptorPool() override;
+
+  vk::DescriptorPool GetVkDescriptorPool() const;
+
+  std::vector<DescriptorSetHandle> AllocateDescriptorSets( vk::DescriptorSetAllocateInfo allocateInfo );
+
+private:
+
+  DescriptorPool( Graphics& graphics, const vk::DescriptorPoolCreateInfo& createInfo );
+
+  class Impl;
+  std::unique_ptr<Impl> mImpl;
+};
+
+
+class DescriptorSetLayout
+{
+public:
+
+  static std::unique_ptr<DescriptorSetLayout> New( Graphics& graphics, const vk::DescriptorSetLayoutCreateInfo& createInfo );
+
+private:
+
+  DescriptorSetLayout( Graphics& graphics, const vk::DescriptorSetLayoutCreateInfo& createInfo );
+
+private:
+
+  class Impl;
+  std::unique_ptr<Impl> mImpl;
+};
+
+} // Namespace Vulkan
+
+} // Namespace Graphics
+
+} // Namespace Dali
+
+#endif // DALI_GRAPHICS_VULKAN_DESCRIPTOR_SET
diff --git a/dali/graphics/vulkan/vulkan-device-memory-manager.cpp b/dali/graphics/vulkan/vulkan-device-memory-manager.cpp
deleted file mode 100644 (file)
index 93f7cb9..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-#include <dali/graphics/vulkan/vulkan-buffer.h>
-#include <dali/graphics/vulkan/vulkan-device-memory-manager.h>
-#include <dali/graphics/vulkan/vulkan-graphics.h>
-#include <dali/graphics/vulkan/vulkan-image.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-namespace Vulkan
-{
-
-namespace
-{
-
-const uint32_t INVALID_MEMORY_INDEX = -1u;
-
-/**
- * Helper function which returns GPU heap index that can be used to allocate
- * particular type of resource
- */
-uint32_t GetMemoryIndex(const vk::PhysicalDeviceMemoryProperties &memoryProperties,
-                        uint32_t memoryTypeBits, vk::MemoryPropertyFlags properties)
-{
-  for(uint32_t i = 0; i < memoryProperties.memoryTypeCount; ++i)
-  {
-    if((memoryTypeBits & (1u << i)) &&
-       ((memoryProperties.memoryTypes[i].propertyFlags & properties) == properties))
-    {
-      return i;
-    }
-  }
-  return INVALID_MEMORY_INDEX;
-}
-}
-
-/*
- * DeviceMemory
- */
-
-DeviceMemory::DeviceMemory(DeviceMemoryManager &manager, Graphics &graphics,
-                           const vk::MemoryRequirements &requirements,
-                           vk::MemoryPropertyFlags       properties)
-: mManager(manager),
-  mGraphics(graphics),
-  mDeviceMemory{nullptr},
-  mProperties{properties},
-  mRequirements(requirements),
-  mUserCount{0u}
-{
-  auto info = vk::MemoryAllocateInfo{};
-  info.setAllocationSize(requirements.size)
-      .setMemoryTypeIndex(
-          GetMemoryIndex(mGraphics.GetMemoryProperties(), requirements.memoryTypeBits, properties));
-
-  mDeviceMemory = VkAssert(mGraphics.GetDevice().allocateMemory(info));
-}
-
-void *DeviceMemory::Map(uint32_t offset, uint32_t size)
-{
-  return nullptr;
-}
-
-void DeviceMemory::Unmap()
-{
-}
-
-void DeviceMemory::Bind(Image &image, uint32_t offset)
-{
-  assert(image.GetImage() && "Image is nullptr!");
-  VkAssert(mGraphics.GetDevice().bindImageMemory(image.GetImage(), mDeviceMemory, offset));
-  ++mUserCount;
-}
-
-void DeviceMemory::Bind(Buffer &image, uint32_t offset)
-{
-}
-
-/*
- * DeviceMemoryManager
- */
-
-DeviceMemoryManager::DeviceMemoryManager(Graphics &graphics) : mGraphics(graphics)
-{
-}
-
-std::unique_ptr< DeviceMemory > DeviceMemoryManager::Allocate(vk::MemoryRequirements  requirements,
-                                                              vk::MemoryPropertyFlags flags)
-{
-  return MakeUnique< DeviceMemory >(*this, mGraphics, requirements, flags);
-}
-
-} // namespace Vulkan
-} // namespace Graphics
-} // namespace Dali
diff --git a/dali/graphics/vulkan/vulkan-device-memory-manager.h b/dali/graphics/vulkan/vulkan-device-memory-manager.h
deleted file mode 100644 (file)
index cf183f0..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-//
-// Created by adam.b on 06/06/17.
-//
-
-#ifndef VULKAN_PROJECT_DEVICEMEMORYMANAGER_H
-#define VULKAN_PROJECT_DEVICEMEMORYMANAGER_H
-
-#include <dali/graphics/vulkan/vulkan-types.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-namespace Vulkan
-{
-
-class Graphics;
-class Image;
-class Buffer;
-class DeviceMemoryManager;
-
-/**
- * DeviceMemory represents continuous memory block with particular properties
- * like being mappable etc. The actual memory is being allocated from DeviceMemory,
- * however simplest use may assume use of whole DeviceMemory block for a single
- * resource/
- */
-class DeviceMemory
-{
-public:
-  DeviceMemory(DeviceMemoryManager& manager, Graphics& graphics,
-               const vk::MemoryRequirements& requirements, vk::MemoryPropertyFlags properties);
-
-  void* Map(uint32_t offset, uint32_t size);
-
-  void Unmap();
-
-  void Bind( Image& image, uint32_t offset );
-  void Bind( Buffer& image, uint32_t offset );
-
-private:
-  DeviceMemoryManager& mManager;
-  Graphics&            mGraphics;
-
-  vk::DeviceMemory        mDeviceMemory;
-  vk::MemoryPropertyFlags mProperties;
-  vk::MemoryRequirements  mRequirements;
-
-  std::atomic< uint32_t > mUserCount; // this is just a refcount
-};
-
-/**
- * DeviceMemoryManager
- */
-class DeviceMemoryManager
-{
-public:
-  DeviceMemoryManager() = delete;
-  DeviceMemoryManager(Graphics& graphics);
-  ~DeviceMemoryManager()                          = default;
-  DeviceMemoryManager(const DeviceMemoryManager&) = delete;
-  DeviceMemoryManager(DeviceMemoryManager&&)      = default;
-
-  DeviceMemoryManager& operator=(const DeviceMemoryManager&) = delete;
-  DeviceMemoryManager& operator=(DeviceMemoryManager&&) = default;
-
-  /* Allocates memory for VkImage */
-  vk::DeviceMemory& Allocate(vk::Image image, vk::MemoryPropertyFlags memoryFlags);
-
-  /* Allocates memory for VkBuffer */
-  vk::DeviceMemory& Allocate(vk::Buffer image, vk::MemoryPropertyFlags memoryFlags);
-
-  std::unique_ptr< DeviceMemory > Allocate(vk::MemoryRequirements  requirements,
-                                           vk::MemoryPropertyFlags flags);
-
-  Graphics& GetGraphics() const
-  {
-    return mGraphics;
-  }
-
-private:
-  Graphics& mGraphics;
-};
-
-} // namespace Vulkan
-} // namespace Graphics
-} // namespace Dali
-
-#endif //VULKAN_PROJECT_DEVICEMEMORYMANAGER_H
index 74dfa18..772a521 100644 (file)
@@ -26,50 +26,127 @@ namespace Graphics
 namespace Vulkan
 {
 
-Fence::Fence(Graphics& graphics) : mGraphics(graphics), mFence(nullptr)
+/**
+ * Class: Fence::Impl
+ *
+ */
+struct Fence::Impl
 {
-  mFence =
-      VkAssert(mGraphics.GetDevice().createFence(vk::FenceCreateInfo{}, mGraphics.GetAllocator()));
-}
+  Impl( Vulkan::Graphics& graphics )
+  : mGraphics( graphics )
+  {
+  }
 
-Fence::~Fence()
-{
-  if(mFence)
+  ~Impl()
   {
-    mGraphics.GetDevice().destroyFence(mFence, mGraphics.GetAllocator());
+    if( mFence )
+    {
+      mGraphics.GetDevice().destroyFence( mFence, mGraphics.GetAllocator() );
+    }
   }
-}
 
-bool Fence::Wait(uint32_t timeout)
-{
-  if(timeout)
+  vk::Result Initialise()
   {
-    return mGraphics.GetDevice().waitForFences(mFence, true, timeout) == vk::Result::eSuccess;
+    mFence = VkAssert( mGraphics.GetDevice().createFence( vk::FenceCreateInfo{}, mGraphics.GetAllocator() ) );
+    if( mFence )
+      return vk::Result::eSuccess;
+    return vk::Result::eErrorInitializationFailed;
   }
-  else
+
+  /**
+   *
+   * @param timeout
+   * @return
+   */
+  bool Wait( uint32_t timeout = 0u )
   {
-    timeout = 16000000;
-    while(mGraphics.GetDevice().waitForFences(mFence, true, timeout) != vk::Result::eSuccess)
+    if(mFence)
     {
-      // fixme: busy wait, bit ugly
+      if(timeout)
+      {
+        return mGraphics.GetDevice().waitForFences(mFence, true, timeout) == vk::Result::eSuccess;
+      }
+      else
+      {
+        timeout = 16000000;
+        while(mGraphics.GetDevice().waitForFences(mFence, true, timeout) != vk::Result::eSuccess)
+        {
+          // fixme: busy wait, bit ugly
+        }
+        return true;
+      }
     }
-    return true;
+    return false;
   }
-}
 
-void Fence::Reset()
+  /**
+   *
+   */
+  void Reset()
+  {
+    if(mFence)
+    {
+      mGraphics.GetDevice().resetFences(mFence);
+    }
+  }
+
+  vk::Fence GetVkFence() const
+  {
+    return mFence;
+  }
+
+  Vulkan::Graphics& mGraphics;
+  vk::Fence mFence;
+};
+
+/**
+ * Class: Fence
+ *
+ */
+Handle<Fence> Fence::New( Graphics& graphics )
 {
-  if(mFence)
+  auto retval = Handle<Fence>( new Fence(graphics) );
+  if( vk::Result::eSuccess == retval->mImpl->Initialise() )
   {
-    mGraphics.GetDevice().resetFences(mFence);
+    return retval;
   }
+  return Handle<Fence>();
+}
+
+Fence::Fence(Graphics& graphics)
+{
+  mImpl = MakeUnique<Impl>(graphics);
+}
+
+const Fence& Fence::ConstRef() const
+{
+  return *this;
+}
+
+Fence& Fence::Ref()
+{
+  return *this;
+}
+
+Fence::~Fence() = default;
+
+bool Fence::Wait(uint32_t timeout)
+{
+  return mImpl->Wait( timeout );
+}
+
+void Fence::Reset()
+{
+  mImpl->Reset();
 }
 
 vk::Fence Fence::GetFence() const
 {
-  return mFence;
+  return mImpl->GetVkFence();
 }
 
+
+
 } // namespace Vulkan
 } // namespace Graphics
 } // namespace Dali
index ea76b6a..db4e6bb 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef DALI_GRAPHICS_VULKAN_FENCE_H
-#define DALI_GRAPHICS_VULKAN_FENCE_H
+#ifndef DALI_GRAPHICS_VULKAN_FENCE
+#define DALI_GRAPHICS_VULKAN_FENCE
 
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -29,27 +29,47 @@ namespace Vulkan
 {
 
 class Graphics;
-class Fence final
+class Fence : public VkManaged
 {
 public:
 
-  Fence( Graphics& graphics );
+  static Handle<Fence> New( Graphics& graphics );
+
   Fence( Fence&& ) = default;
   ~Fence();
 
+private:
+
+  Fence( Graphics& graphics );
+
+public:
+
+  const Fence& ConstRef() const;
+
+  Fence& Ref();
+
+  /**
+   *
+   * @param timeout
+   * @return
+   */
   bool Wait( uint32_t timeout = 0u );
+
+  /**
+   *
+   */
   void Reset();
 
   vk::Fence GetFence() const;
 
 private:
 
-  Graphics& mGraphics;
-  vk::Fence mFence;
+  class Impl;
+  std::unique_ptr<Impl> mImpl;
 };
 
 } // namespace Vulkan
 } // namespace Graphics
 } // namespace Dali
 
-#endif // DALI_GRAPHICS_VULKAN_FENCE_H
+#endif // DALI_GRAPHICS_VULKAN_FENCE
diff --git a/dali/graphics/vulkan/vulkan-framebuffer.cpp b/dali/graphics/vulkan/vulkan-framebuffer.cpp
new file mode 100644 (file)
index 0000000..ecd334a
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali/graphics/vulkan/vulkan-framebuffer.h>
+#include <dali/graphics/vulkan/vulkan-graphics.h>
+#include <dali/graphics/vulkan/vulkan-image.h>
+
+namespace Dali
+{
+namespace Graphics
+{
+namespace Vulkan
+{
+
+struct Framebuffer::Impl
+{
+  Impl( Framebuffer& owner, Graphics& graphics, uint32_t width, uint32_t height ) :
+    mInterface( owner ),
+    mGraphics( graphics )
+  {
+
+  }
+
+  // Framebuffer creation may be deferred
+  bool Initialise()
+  {
+    if(mInitialised)
+    {
+      return true;
+    }
+
+    if(!Validate())
+    {
+      return false;
+    }
+
+    /*
+    auto attRef = vk::AttachmentReference{};
+    attRef.setLayout();
+    attRef.setAttachment();
+
+    // creating single subpass per framebuffer
+    auto subpassDesc = vk::SubpassDescription{};
+    subpassDesc.setPipelineBindPoint( vk::PipelineBindPoint::eGraphics );
+    subpassDesc.setColorAttachmentCount(0);
+    subpassDesc.setInputAttachmentCount(0);
+    subpassDesc.setPDepthStencilAttachment(nullptr);
+    subpassDesc.setPColorAttachments( nullptr );
+    subpassDesc.setPInputAttachments( nullptr );
+    subpassDesc.setPPreserveAttachments( nullptr );
+    subpassDesc.setPResolveAttachments( nullptr );
+
+
+    auto rpInfo = vk::RenderPassCreateInfo{};
+    rpInfo.setAttachmentCount( mAttachments.size() );
+    //rpInfo.setPAttachments( )
+    rpInfo.setDependencyCount( 0 );
+    rpInfo.setPDependencies( nullptr );
+    rpInfo.setPSubpasses( &subpassDesc );
+    rpInfo.setSubpassCount( 1 );
+
+    auto fbInfo = vk::FramebufferCreateInfo{};
+    fbInfo.setWidth( mWidth );
+    fbInfo.setHeight( mHeight );
+    //fbInfo.setRenderPass( )
+    //fbInfo.setAttachmentCount( 0 );
+    //fbInfo.setPAttachments( ImageViews );
+    */
+    mInitialised = true;
+  }
+
+
+  void SetAttachment( Handle<Image> image, Framebuffer::AttachmentType type, uint32_t index )
+  {
+    std::vector<Handle<Image>>& attachments =
+      type == AttachmentType::COLOR ? mColorAttachments : mDepthStencilAttachments;
+
+    if( attachments.size() <= index )
+    {
+      attachments.resize( index+1 );
+    }
+    attachments[index] = image;
+  }
+
+  ImageRef GetAttachmentImage( AttachmentType type, uint32_t index ) const
+  {
+    return ImageRef();
+  }
+
+  ImageViewRef GetAttachmentImageView( AttachmentType type, uint32_t index ) const
+  {
+    return ImageViewRef();
+  }
+
+  bool Validate()
+  {
+    if( mWidth == 0u || mHeight == 0  )
+    {
+      return false;
+    }
+  }
+
+  ~Impl()
+  {
+
+  }
+
+  vk::RenderPass GetVkRenderPass() const
+  {
+    return mVkRenderPass;
+  }
+
+  vk::Framebuffer GetVkFramebuffer() const
+  {
+    return mVkFramebuffer;
+  }
+
+  Framebuffer&            mInterface;
+  Graphics&               mGraphics;
+
+  uint32_t mWidth;
+  uint32_t mHeight;
+  std::vector<Handle<Image>>      mColorAttachments;
+  std::vector<Handle<Image>>      mDepthStencilAttachments;
+
+  std::vector<ImageView>  mImageViewAttachments;
+  vk::Framebuffer         mVkFramebuffer;
+  vk::RenderPass          mVkRenderPass;
+
+  bool mInitialised { false };
+};
+
+
+Handle<Framebuffer> Framebuffer::New( Graphics& graphics, uint32_t width, uint32_t height )
+{
+  return FramebufferRef();
+}
+
+void Framebuffer::SetAttachment( Handle<Image> image, Framebuffer::AttachmentType type, uint32_t index )
+{
+  mImpl->SetAttachment( image, type, index );
+}
+
+uint32_t Framebuffer::GetWidth() const
+{
+  return mImpl->mWidth;
+}
+
+uint32_t Framebuffer::GetHeight() const
+{
+  return mImpl->mHeight;
+}
+
+Handle<Image> Framebuffer::GetAttachmentImage( AttachmentType type, uint32_t index ) const
+{
+  return mImpl->GetAttachmentImage( type, index );
+}
+
+Handle<ImageView> Framebuffer::GetAttachmentImageView( AttachmentType type, uint32_t index ) const
+{
+  return mImpl->GetAttachmentImageView( type, index );
+}
+
+} // Namespace Vulkan
+
+} // Namespace Graphics
+
+} // Namespace Dali
diff --git a/dali/graphics/vulkan/vulkan-framebuffer.h b/dali/graphics/vulkan/vulkan-framebuffer.h
new file mode 100644 (file)
index 0000000..3cb5918
--- /dev/null
@@ -0,0 +1,76 @@
+#ifndef DALI_GRAPHICS_VULKAN_FRAMEBUFFER
+#define DALI_GRAPHICS_VULKAN_FRAMEBUFFER
+
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali/graphics/vulkan/vulkan-types.h>
+namespace Dali
+{
+namespace Graphics
+{
+namespace Vulkan
+{
+
+class Image;
+
+/**
+ * Framebuffer encapsulates following objects:
+ * - Images ( attachments )
+ * - Framebuffer
+ * - ImageViews
+ */
+class Framebuffer : public VkManaged
+{
+public:
+
+  enum class AttachmentType
+  {
+    COLOR,
+    DEPTH_STENCIL,
+    INPUT,
+    RESOLVE,
+    PRESERVE
+  };
+
+  static Handle<Framebuffer> New( Graphics& graphics, uint32_t width, uint32_t height );
+
+  uint32_t GetWidth() const;
+
+  uint32_t GetHeight() const;
+
+  Handle<Image> GetAttachmentImage( AttachmentType type, uint32_t index ) const;
+
+  Handle<ImageView> GetAttachmentImageView( AttachmentType type, uint32_t index ) const;
+
+  void SetAttachment( Handle<Image> image, Framebuffer::AttachmentType type, uint32_t index );
+
+private:
+
+  class Impl;
+  std::unique_ptr<Impl> mImpl;
+
+};
+
+
+} // Namespace Vulkan
+
+} // Namespace Graphics
+
+} // Namespace Dali
+
+#endif // DALI_GRAPHICS_VULKAN_FRAMEBUFFER
index 1ad1ff2..ae4b42e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include <dali/graphics/vulkan/vulkan-queue.h>
 #include <dali/graphics/vulkan/vulkan-surface.h>
 #include <dali/integration-api/graphics/vulkan/vk-surface-factory.h>
-#include <dali/graphics/vulkan/vulkan-device-memory-manager.h>
+#include <dali/graphics/vulkan/gpu-memory/vulkan-gpu-memory-manager.h>
+
+#include <dali/graphics/vulkan/vulkan-buffer.h>
+#include <dali/graphics/vulkan/vulkan-image.h>
+#include <dali/graphics/vulkan/vulkan-pipeline.h>
+#include <dali/graphics/vulkan/vulkan-shader.h>
+#include <dali/graphics/vulkan/vulkan-descriptor-set.h>
+#include <dali/graphics/vulkan/vulkan-framebuffer.h>
 
 #ifndef VK_KHR_XLIB_SURFACE_EXTENSION_NAME
 #define VK_KHR_XLIB_SURFACE_EXTENSION_NAME "VK_KHR_xlib_surface"
 #endif
 
+#ifndef VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME
+#define VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME "VK_KHR_wayland_surface"
+#endif
+
 #ifndef VK_KHR_XCB_SURFACE_EXTENSION_NAME
 #define VK_KHR_XCB_SURFACE_EXTENSION_NAME "VK_KHR_xcb_surface"
 #endif
 
+#include <iostream>
+
 namespace Dali
 {
 namespace Graphics
@@ -39,36 +52,145 @@ using VkSurfaceFactory = Dali::Integration::Graphics::Vulkan::VkSurfaceFactory;
 namespace Vulkan
 {
 
+const auto VALIDATION_LAYERS = std::vector< const char* >{
+
+  //"VK_LAYER_LUNARG_screenshot",           // screenshot
+  "VK_LAYER_RENDERDOC_Capture",
+  "VK_LAYER_LUNARG_parameter_validation", // parameter
+  //"VK_LAYER_LUNARG_vktrace",              // vktrace ( requires vktrace connection )
+  "VK_LAYER_LUNARG_monitor",             // monitor
+  "VK_LAYER_LUNARG_swapchain",           // swapchain
+  "VK_LAYER_GOOGLE_threading",           // threading
+  "VK_LAYER_LUNARG_api_dump",            // api
+  "VK_LAYER_LUNARG_object_tracker",      // objects
+  "VK_LAYER_LUNARG_core_validation",     // core
+  "VK_LAYER_GOOGLE_unique_objects",      // unique objects
+  "VK_LAYER_LUNARG_standard_validation", // standard
+};
+
 Graphics::Graphics() = default;
 
 Graphics::~Graphics() = default;
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wframe-larger-than="
+
+Platform Graphics::GetDefaultPlatform() const
+{
+#ifdef VK_USE_PLATFORM_WAYLAND_KHR
+  mPlatform = Platform::WAYLAND;
+#elif VK_USE_PLATFORM_XCB_KHR
+  mPlatform = Platform::XCB;
+#elif VK_USE_PLATFORM_XLIB_KHR
+  mPlatform =  Platform::XLIB;
+#else
+  return mPlatform;
+#endif
+}
+
+std::vector<const char*> Graphics::PrepareDefaultInstanceExtensions()
+{
+  auto extensions = vk::enumerateInstanceExtensionProperties();
+
+  std::string extensionName;
+
+  bool xlibAvailable    { false };
+  bool xcbAvailable     { false };
+  bool waylandAvailable { false };
+
+  for( auto&& ext : extensions.value )
+  {
+    extensionName = ext.extensionName;
+    if( extensionName == VK_KHR_XCB_SURFACE_EXTENSION_NAME )
+    {
+      xcbAvailable = true;
+    }
+    else if( extensionName == VK_KHR_XLIB_SURFACE_EXTENSION_NAME )
+    {
+      xlibAvailable = true;
+    }
+    else if( extensionName == VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME )
+    {
+      waylandAvailable = true;
+    }
+  }
+
+  std::vector<const char*> retval;
+
+  // depending on the platform validate extensions
+  auto platform = GetDefaultPlatform();
+
+  if( platform != Platform::UNDEFINED )
+  {
+    if (platform == Platform::XCB && xcbAvailable)
+    {
+      retval.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
+    }
+    else if (platform == Platform::XLIB && xlibAvailable)
+    {
+      retval.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
+    }
+    else if (platform == Platform::WAYLAND && waylandAvailable)
+    {
+      retval.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
+    }
+  }
+  else // try to determine the platform based on available extensions
+  {
+    if (xcbAvailable)
+    {
+      mPlatform = Platform::XCB;
+      retval.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
+    }
+    else if (xlibAvailable)
+    {
+      mPlatform = Platform::XLIB;
+      retval.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
+    }
+    else if (waylandAvailable)
+    {
+      mPlatform = Platform::WAYLAND;
+      retval.push_back(VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME);
+    }
+    else
+    {
+      // can't determine the platform!
+      mPlatform = Platform::UNDEFINED;
+    }
+  }
+
+  // other essential extensions
+  retval.push_back( VK_KHR_SURFACE_EXTENSION_NAME );
+  retval.push_back( VK_EXT_DEBUG_REPORT_EXTENSION_NAME );
+
+  return retval;
+}
 
 void Graphics::Create()
 {
-  CreateInstance();
+
+  auto extensions = PrepareDefaultInstanceExtensions();
+
+  auto layers = vk::enumerateInstanceLayerProperties();
+  std::vector<const char*> validationLayers;
+  for( auto&& reqLayer : VALIDATION_LAYERS )
+  {
+    for( auto&& prop : layers.value )
+    {
+      //std::cout << prop.layerName << std::endl;
+      if( std::string(prop.layerName) == reqLayer )
+      {
+        validationLayers.push_back(reqLayer);
+      }
+    }
+  }
+
+  CreateInstance(extensions, validationLayers);
   PreparePhysicalDevice();
 }
 
-void Graphics::CreateInstance()
+void Graphics::CreateInstance( const std::vector<const char*>& extensions, const std::vector<const char*>& validationLayers )
 {
   auto info = vk::InstanceCreateInfo{};
-  auto extensions =
-      std::vector< const char* >{VK_KHR_SURFACE_EXTENSION_NAME, VK_EXT_DEBUG_REPORT_EXTENSION_NAME,
-                                 VK_KHR_XLIB_SURFACE_EXTENSION_NAME, VK_KHR_XCB_SURFACE_EXTENSION_NAME };
-
-  const auto validationLayers = std::vector< const char* >{
-      //"VK_LAYER_LUNARG_screenshot",           // screenshot
-      "VK_LAYER_LUNARG_parameter_validation", // parameter
-      //"VK_LAYER_LUNARG_vktrace",              // vktrace ( requires vktrace connection )
-      "VK_LAYER_LUNARG_monitor",             // monitor
-      "VK_LAYER_LUNARG_swapchain",           // swapchain
-      "VK_LAYER_GOOGLE_threading",           // threading
-      "VK_LAYER_LUNARG_api_dump",            // api
-      "VK_LAYER_LUNARG_object_tracker",      // objects
-      "VK_LAYER_LUNARG_core_validation",     // core
-      "VK_LAYER_GOOGLE_unique_objects",      // unique objects
-      "VK_LAYER_LUNARG_standard_validation", // standard
-  };
 
   info.setEnabledExtensionCount(U32(extensions.size()))
       .setPpEnabledExtensionNames(extensions.data())
@@ -87,8 +209,7 @@ void Graphics::DestroyInstance()
   }
 }
 
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wframe-larger-than="
+
 void Graphics::PreparePhysicalDevice()
 {
   auto devices = VkAssert(mInstance.enumeratePhysicalDevices());
@@ -120,7 +241,7 @@ void Graphics::PreparePhysicalDevice()
 
   GetQueueFamilyProperties();
 
-  mDeviceMemoryManager = MakeUnique<DeviceMemoryManager>( *this );
+  mDeviceMemoryManager = GpuMemoryManager::New( *this );
 }
 #pragma GCC diagnostic pop
 
@@ -357,17 +478,114 @@ Queue& Graphics::GetPresentQueue() const
   return *mPresentQueue.get();
 }
 
-std::unique_ptr< CommandPool > Graphics::CreateCommandPool(const vk::CommandPoolCreateInfo& info)
+Handle< CommandPool > Graphics::CreateCommandPool(const vk::CommandPoolCreateInfo& info)
 {
-  auto cmdpool = std::unique_ptr< CommandPool >(new CommandPool(*this, info));
+  auto cmdpool = CommandPool::New( *this, vk::CommandPoolCreateInfo{}.
+                                                                       setQueueFamilyIndex( 0u ).
+                                                                       setFlags( vk::CommandPoolCreateFlagBits::eResetCommandBuffer ) );
   return cmdpool;
 }
 
 Surface& Graphics::GetSurface( FBID surfaceId )
 {
+  // TODO: FBID == 0 means default framebuffer, but there should be no
+  // such thing as default framebuffer.
+  if( surfaceId == 0 )
+  {
+    return *mSurfaceFBIDMap.begin()->second.get();
+  }
   return *mSurfaceFBIDMap[surfaceId].get();
 }
 
+// TODO: all this stuff should go into some vulkan cache
+
+void Graphics::AddBuffer( Handle<Buffer> buffer )
+{
+  mBuffersCache.push_back( buffer );
+}
+
+void Graphics::AddImage( Handle<Image> image )
+{
+  mImageCache.push_back( image );
+}
+
+void Graphics::AddPipeline( Handle<Pipeline> pipeline )
+{
+  mPipelineCache.push_back( pipeline );
+}
+
+void Graphics::AddShader( Handle<Shader> shader )
+{
+  mShaderCache.push_back( shader );
+}
+
+void Graphics::AddCommandPool( Handle<CommandPool> pool )
+{
+  mCommandPoolCache.push_back( pool );
+}
+
+void Graphics::AddDescriptorPool( Handle<DescriptorPool> pool )
+{
+  mDescriptorPoolCache.push_back( pool );
+}
+
+void Graphics::AddFramebuffer( Handle<Framebuffer> framebuffer )
+{
+  mFramebufferCache.push_back( framebuffer );
+}
+
+void Graphics::RemoveBuffer( Buffer& buffer )
+{
+  auto index = 0u;
+  for( auto&& iter : mBuffersCache )
+  {
+    if( &*iter == &buffer )
+    {
+      iter.Reset();
+      mBuffersCache.erase( mBuffersCache.begin()+index );
+      return;
+    }
+  }
+}
+
+void Graphics::RemoveShader( Shader& shader )
+{
+  auto index = 0u;
+  for( auto&& iter : mShaderCache )
+  {
+    if( &*iter == &shader )
+    {
+      iter.Reset();
+      mShaderCache.erase( mShaderCache.begin()+index );
+      return;
+    }
+    ++index;
+  }
+}
+
+void Graphics::RemoveCommandPool( CommandPool& commandPool )
+{
+  NotImplemented();
+}
+
+void Graphics::RemoveDescriptorPool( std::unique_ptr<DescriptorPool> pool )
+{
+  NotImplemented();
+}
+
+Handle<Shader> Graphics::FindShader( vk::ShaderModule shaderModule )
+{
+  for( auto&& iter : mShaderCache )
+  {
+    if( iter->GetVkShaderModule() == shaderModule )
+    {
+      return Handle<Shader>(&*iter);
+    }
+  }
+  return Handle<Shader>();
+}
+
+
 } // namespace Vulkan
 } // namespace Graphics
 } // namespace Dali
index 5e4c9e9..aa5298e 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef DALI_GRAPHICS_VULKAN_GRAPHICS_H
-#define DALI_GRAPHICS_VULKAN_GRAPHICS_H
+#ifndef DALI_GRAPHICS_VULKAN_GRAPHICS
+#define DALI_GRAPHICS_VULKAN_GRAPHICS
 
 /*
  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
@@ -35,9 +35,23 @@ using SurfaceFactory = Dali::Integration::Graphics::SurfaceFactory;
 namespace Vulkan
 {
 
+enum class Platform
+{
+  UNDEFINED,
+  XLIB,
+  XCB,
+  WAYLAND,
+};
+
+class Buffer;
+class Image;
+class Pipeline;
+class Shader;
+class Framebuffer;
 class Surface;
 class CommandPool;
-class DeviceMemoryManager;
+class DescriptorPool;
+class GpuMemoryManager;
 class Graphics
 {
 
@@ -58,7 +72,7 @@ public:
   void CreateDevice();
 
   /** Creates new command pool */
-  std::unique_ptr< CommandPool > CreateCommandPool(const vk::CommandPoolCreateInfo& info);
+  CommandPoolRef CreateCommandPool(const vk::CommandPoolCreateInfo& info);
 
   vk::Device GetDevice() const;
 
@@ -68,7 +82,7 @@ public:
 
   const vk::AllocationCallbacks& GetAllocator() const;
 
-  DeviceMemoryManager& GetDeviceMemoryManager() const
+  GpuMemoryManager& GetDeviceMemoryManager() const
   {
     return *mDeviceMemoryManager;
   }
@@ -83,18 +97,21 @@ public:
   Queue& GetComputeQueue(uint32_t index = 0u) const;
   Queue& GetPresentQueue() const;
 
+  Platform GetDefaultPlatform() const;
+
 private:
 
-  void                                     CreateInstance();
+  void                                     CreateInstance( const std::vector<const char*>& extensions, const std::vector<const char*>& validationLayers );
   void                                     DestroyInstance();
   void                                     PreparePhysicalDevice();
   void                                     GetPhysicalDeviceProperties();
   void                                     GetQueueFamilyProperties();
   std::vector< vk::DeviceQueueCreateInfo > GetQueueCreateInfos();
+  std::vector<const char*>                 PrepareDefaultInstanceExtensions();
 
 private:
 
-  std::unique_ptr<DeviceMemoryManager> mDeviceMemoryManager;
+  std::unique_ptr<GpuMemoryManager> mDeviceMemoryManager;
 
   vk::Instance             mInstance;
   std::unique_ptr<vk::AllocationCallbacks> mAllocator{nullptr};
@@ -121,10 +138,39 @@ private:
   std::vector< std::unique_ptr<Queue> >  mTransferQueues;
   std::vector< std::unique_ptr<Queue> >  mComputeQueues;
   std::unique_ptr< Queue > mPresentQueue;
+
+  Platform                               mPlatform  { Platform::UNDEFINED };
+
+public:
+  // TODO: all this stuff should go into some vulkan cache
+
+  void AddBuffer( Handle<Buffer> buffer );
+  void AddImage( Handle<Image> image );
+  void AddPipeline( Handle<Pipeline> pipeline );
+  void AddShader( Handle<Shader> shader );
+  void AddCommandPool( Handle<CommandPool> pool );
+  void AddDescriptorPool( Handle<DescriptorPool> pool );
+  void AddFramebuffer( Handle<Framebuffer> framebuffer );
+
+  ShaderRef FindShader( vk::ShaderModule shaderModule );
+
+  void RemoveBuffer( Buffer& buffer );
+  void RemoveShader( Shader& shader );
+  void RemoveCommandPool( CommandPool& commandPool );
+  void RemoveDescriptorPool( std::unique_ptr<DescriptorPool> pool );
+
+private:
+  std::vector<BufferRef>                mBuffersCache;
+  std::vector<ImageRef>                 mImageCache;
+  std::vector<PipelineRef>              mPipelineCache;
+  std::vector<ShaderRef>                mShaderCache;
+  std::vector<CommandPoolRef>           mCommandPoolCache;
+  std::vector<DescriptorPoolRef>        mDescriptorPoolCache;
+  std::vector<FramebufferRef>           mFramebufferCache;
 };
 
 } // namespace Vulkan
 } // namespace Graphics
 } // namespace Dali
 
-#endif // DALI_GRAPHICS_VULKAN_GRAPHICS_H
+#endif // DALI_GRAPHICS_VULKAN_GRAPHICS
index 50e05e0..5ec2477 100644 (file)
@@ -40,17 +40,17 @@ vk::ImageView Image::CreateUnmanagedView(const vk::ImageViewCreateInfo& info)
   return nullptr;
 }
 
-UniqueImageView Image::CreateView(const vk::ImageViewCreateInfo& info)
+ImageViewRef Image::CreateView(const vk::ImageViewCreateInfo& info)
 {
-  return MakeUnique< ImageView >(mGraphics, *this, info);
+  return MakeRef< ImageView >(mGraphics, *this, info);
 }
 
-ImageView::ImageView(Graphics& graphics, Image& image) : mGraphics(graphics), mImageRef(image)
+ImageView::ImageView(Graphics& graphics, Image& image) : mGraphics(graphics), mImageRef(&image)
 {
 }
 
 ImageView::ImageView(Graphics& graphics, Image& image, const VkImageViewCreateInfo& createInfo)
-: mGraphics(graphics), mImageRef(image)
+: mGraphics(graphics), mImageRef(&image)
 {
   mImageView =
       VkAssert(mGraphics.GetDevice().createImageView(createInfo, mGraphics.GetAllocator()));
index ff29ffa..aefb4e9 100644 (file)
@@ -1,5 +1,5 @@
-#ifndef DALI_GRAPHICS_VULKAN_IMAGE_H
-#define DALI_GRAPHICS_VULKAN_IMAGE_H
+#ifndef DALI_GRAPHICS_VULKAN_IMAGE
+#define DALI_GRAPHICS_VULKAN_IMAGE
 
 /*
  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
@@ -34,7 +34,7 @@ enum class ResourceOwnershipType
   EXTERNAL
 };
 
-class Image : public Resource
+class Image : public VkManaged
 {
 public:
   /**
@@ -75,7 +75,7 @@ public:
    * @param info
    * @return
    */
-  UniqueImageView CreateView(const vk::ImageViewCreateInfo& info);
+  ImageViewRef CreateView(const vk::ImageViewCreateInfo& info);
 
   /**
    * Returns underlying Vulkan object
@@ -100,7 +100,7 @@ private:
  * ImageView
  * todo: move it to its own file
  */
-class ImageView : public Resource
+class ImageView : public VkManaged
 {
 public:
   ImageView(Graphics& graphics, Image& image);
@@ -115,12 +115,13 @@ public:
 
   Image& GetImage() const
   {
-    return mImageRef.GetResource();
+    return *mImageRef;
   }
 
 private:
+
   Graphics&             mGraphics;
-  ResourceRef<Image>    mImageRef;
+  Handle<Image>         mImageRef;
 
   vk::ImageView mImageView;
 };
@@ -131,4 +132,4 @@ private:
 
 } // namespace Dali
 
-#endif // DALI_GRAPHICS_VULKAN_IMAGE_H
+#endif // DALI_GRAPHICS_VULKAN_IMAGE
diff --git a/dali/graphics/vulkan/vulkan-pipeline.cpp b/dali/graphics/vulkan/vulkan-pipeline.cpp
new file mode 100644 (file)
index 0000000..e9c0219
--- /dev/null
@@ -0,0 +1,396 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali/graphics/vulkan/vulkan-pipeline.h>
+#include <dali/graphics/vulkan/vulkan-graphics.h>
+#include <dali/graphics/vulkan/vulkan-surface.h>
+
+namespace Dali
+{
+namespace Graphics
+{
+namespace Vulkan
+{
+
+/**
+ * Class Pipeline::Impl
+ * Internal implementation of the pipeline
+ */
+struct Pipeline::Impl
+{
+  Impl( Vulkan::Graphics& graphics, const vk::GraphicsPipelineCreateInfo& info ) :
+    mInfo( info ),
+    mGraphics( graphics )
+  {
+  };
+
+  Impl() = default;
+  ~Impl()
+  {
+    if(mPipelineLayout)
+    {
+      mGraphics.GetDevice().destroyPipelineLayout( mPipelineLayout, mGraphics.GetAllocator() );
+    }
+    if(mPipeline)
+    {
+      mGraphics.GetDevice().destroyPipeline( mPipeline, mGraphics.GetAllocator() );
+    }
+  }
+
+  /**
+   *
+   * @return
+   */
+  vk::Pipeline GetVkPipeline() const
+  {
+    return mPipeline;
+  }
+
+  vk::Result Initialise()
+  {
+    if( !ValidateShaderModules() )
+    {
+      return vk::Result::eErrorInitializationFailed;
+    }
+
+    CreatePipelineLayout();
+
+    // use default render pass for default framebuffer
+    // TODO: swapchain/surface should use vulkan-framebuffer object
+    // in place of swapchain structures!
+    if( !mInfo.renderPass )
+    {
+      SetRenderPass( mGraphics.GetSurface( 0 ).GetRenderPass() );
+    }
+
+    SetRasterizationState();
+
+    SetDepthStencilState();
+
+    SetMultisampleState();
+
+    SetColorBlendState();
+
+    mInfo.setFlags( vk::PipelineCreateFlagBits::eAllowDerivatives );
+    // create pipeline
+    mPipeline = VkAssert( mGraphics.GetDevice().createGraphicsPipeline( nullptr, mInfo, mGraphics.GetAllocator() ) );
+    if(mPipeline)
+    {
+      return vk::Result::eSuccess;
+    }
+    return vk::Result::eErrorInitializationFailed;
+  }
+
+  void SetRenderPass( vk::RenderPass renderpass )
+  {
+    mInfo.setRenderPass( renderpass );
+  }
+
+  void SetDepthStencilState()
+  {
+    mDepthStencilState = vk::PipelineDepthStencilStateCreateInfo{};
+    mDepthStencilState.setDepthBoundsTestEnable( false );
+    mDepthStencilState.setStencilTestEnable( false );
+    mInfo.setPDepthStencilState( & mDepthStencilState );
+  }
+
+  void SetMultisampleState()
+  {
+    mMultisampleState = vk::PipelineMultisampleStateCreateInfo{};
+    mMultisampleState.setSampleShadingEnable( false );
+    mMultisampleState.setRasterizationSamples( vk::SampleCountFlagBits::e1);
+    mMultisampleState.setAlphaToCoverageEnable( false );
+    mMultisampleState.setMinSampleShading( 1.0f );
+    mMultisampleState.setPSampleMask( nullptr );
+    mInfo.setPMultisampleState( &mMultisampleState );
+  }
+
+  void SetVertexInputState(
+    std::vector<vk::VertexInputAttributeDescription> attrDesc,
+    std::vector<vk::VertexInputBindingDescription> bindingDesc)
+  {
+    mBindingDesc.clear();
+    mAttrDesc.clear();
+    mVertexInputState = vk::PipelineVertexInputStateCreateInfo{};
+    mVertexInputState.setPVertexAttributeDescriptions( (mAttrDesc = attrDesc).data() );
+    mVertexInputState.setPVertexBindingDescriptions( (mBindingDesc = bindingDesc).data() );
+    mVertexInputState.setVertexAttributeDescriptionCount( U32(mAttrDesc.size()) );
+    mVertexInputState.setVertexBindingDescriptionCount( U32(mBindingDesc.size()) );
+    mInfo.setPVertexInputState( &mVertexInputState );
+  }
+
+  /**
+   * Sets the viewport on uncompiled pipeline
+   * @return
+   */
+  void SetViewport( float x, float y, float width, float height )
+  {
+    assert( !mPipeline && "Pipeline cannot be changed anymore!");
+
+    // AB: add scissor, read data from graphics for fullscreen viewport
+    // simplified mode for the demo purposes
+    mViewports.emplace_back( x, y, width, height );
+    mViewports[0].setMinDepth( 0.0f );
+    mViewports[0].setMaxDepth( 1.0f );
+    mScissors = vk::Rect2D( { static_cast<int32_t>(x), static_cast<int32_t>(y) },
+                            { U32(width), U32(height) });
+    mViewportState = vk::PipelineViewportStateCreateInfo{}.
+           setViewportCount( U32(mViewports.size()) ).
+           setPViewports( mViewports.data() ).
+           setPScissors( &mScissors ).
+           setScissorCount( 1 );
+
+    // replace viewport state
+    mInfo.setPViewportState( &mViewportState );
+  }
+
+  /**
+   *
+   * @param topology
+   * @param restartEnable
+   */
+  void SetInputAssemblyState( vk::PrimitiveTopology topology, bool restartEnable )
+  {
+    mInputAssemblyState = vk::PipelineInputAssemblyStateCreateInfo{};
+    mInputAssemblyState.setPrimitiveRestartEnable( restartEnable );
+    mInputAssemblyState.setTopology( topology );
+    mInfo.setPInputAssemblyState( &mInputAssemblyState );
+  }
+
+  void SetRasterizationState()
+  {
+    mRasterizationState = vk::PipelineRasterizationStateCreateInfo{};
+    mRasterizationState.setCullMode( vk::CullModeFlagBits::eNone );
+    mRasterizationState.setDepthBiasClamp( 0.0f );
+    mRasterizationState.setDepthBiasEnable( false );
+    mRasterizationState.setDepthClampEnable( false );
+    mRasterizationState.setFrontFace( vk::FrontFace::eClockwise );
+    mRasterizationState.setPolygonMode( vk::PolygonMode::eFill );
+    mRasterizationState.setRasterizerDiscardEnable( false );
+    mRasterizationState.setLineWidth( 1.0f );
+    mInfo.setPRasterizationState( & mRasterizationState );
+  }
+
+  void SetColorBlendState()
+  {
+    mAttachementNoBlendState = vk::PipelineColorBlendAttachmentState{};
+    //mAttachementNoBlendState.setBlendEnable( true );
+    mAttachementNoBlendState.setColorWriteMask( vk::ColorComponentFlagBits::eR |
+                                                  vk::ColorComponentFlagBits::eG |
+                                                  vk::ColorComponentFlagBits::eB |
+                                                  vk::ColorComponentFlagBits::eA );
+
+    mColorBlendState.setBlendConstants( { 1.0f, 1.0f, 1.0f, 1.0f });
+    mColorBlendState = vk::PipelineColorBlendStateCreateInfo{};
+    mColorBlendState.setAttachmentCount( 1 );
+    mColorBlendState.setPAttachments( &mAttachementNoBlendState );
+    mInfo.setPColorBlendState(&mColorBlendState);
+  }
+
+  /**
+   * Sets the shader. Must be set before compiling the pipeline, compiled pipeline
+   * becomes immutable.
+   * @param shader
+   * @param stage
+   * @return
+   */
+  bool SetShader( ShaderRef shader, Shader::Type stage )
+  {
+    assert( !mPipeline && "Pipeline cannot be changed anymore!");
+
+    // check if shader isn't orphaned for some reason
+    if( !mGraphics.FindShader( *shader ) )
+    {
+      return false;
+    }
+
+    auto info = vk::PipelineShaderStageCreateInfo{}.
+                                                     setModule( *shader ).
+                                                     setStage( static_cast<vk::ShaderStageFlagBits>( stage ) ).
+                                                     setPName( "main" );
+
+    mShaderStageCreateInfo.push_back( info );
+    mShaderResources.push_back( shader );
+
+    mInfo.setPStages( mShaderStageCreateInfo.data() );
+    mInfo.setStageCount( static_cast<uint32_t>(mShaderStageCreateInfo.size()) );
+
+    return false;
+  }
+
+  /**
+   *
+   */
+  void CreatePipelineLayout()
+  {
+    // pull desciptor set layouts from shaders
+    auto layoutInfo = vk::PipelineLayoutCreateInfo{};
+
+    //info.setPSetLayouts( vk::DescriptorSetLayout )
+
+    std::vector<vk::DescriptorSetLayout> allLayouts{};
+    for( auto&& shader : mShaderResources )
+    {
+      auto& layouts = shader->GetDescriptorSetLayouts();
+      if( layouts.size() )
+      {
+        allLayouts.resize(layouts.size());
+        for (auto i = 0u; i < layouts.size(); ++i)
+        {
+          if (layouts[i])
+          {
+            allLayouts[i] = layouts[i];
+          }
+        }
+      }
+    }
+
+    layoutInfo.setPSetLayouts( allLayouts.data() );
+    layoutInfo.setSetLayoutCount( static_cast<uint32_t>(allLayouts.size()) );
+
+    mPipelineLayout = VkAssert( mGraphics.GetDevice().createPipelineLayout( layoutInfo, mGraphics.GetAllocator() ) );
+
+    mInfo.setLayout( mPipelineLayout );
+  }
+
+
+  bool Compile()
+  {
+    return Initialise() == vk::Result::eSuccess;
+  }
+
+  bool ValidateShaderModules()
+  {
+    for( auto i = 0u; i < mInfo.stageCount; ++i )
+    {
+      const auto& stage = mInfo.pStages[i];
+      auto shaderHandle = mGraphics.FindShader( stage.module );
+      if( shaderHandle )
+      {
+        mShaderResources.push_back( shaderHandle );
+      }
+      else
+      {
+        return false; // invalid shader! Can't track it
+      }
+    }
+    return true;
+  }
+
+
+  vk::GraphicsPipelineCreateInfo  mInfo           {    };
+  vk::Pipeline                    mPipeline       { nullptr };
+  uint32_t                        mModified       { 0u };
+  Graphics&                       mGraphics;
+
+  // resources
+  std::vector<Handle<Shader>>     mShaderResources;
+
+  vk::PipelineViewportStateCreateInfo mViewportState {};
+  std::vector<vk::Viewport> mViewports {};
+  vk::Rect2D mScissors {};
+
+  std::vector<vk::PipelineShaderStageCreateInfo> mShaderStageCreateInfo;
+  vk::PipelineLayout mPipelineLayout{};
+
+  // vertex input state
+  vk::PipelineVertexInputStateCreateInfo            mVertexInputState {};
+  std::vector<vk::VertexInputAttributeDescription>  mAttrDesc;
+  std::vector<vk::VertexInputBindingDescription>    mBindingDesc;
+
+  // vertex input assembly state
+  vk::PipelineInputAssemblyStateCreateInfo          mInputAssemblyState {};
+
+  // rasterization state
+  vk::PipelineRasterizationStateCreateInfo          mRasterizationState {};
+
+  // Dpeth/stencil state
+  vk::PipelineDepthStencilStateCreateInfo           mDepthStencilState {};
+
+  // Multisample state
+  vk::PipelineMultisampleStateCreateInfo            mMultisampleState {};
+
+  // Color blend
+  vk::PipelineColorBlendStateCreateInfo             mColorBlendState {};
+  vk::PipelineColorBlendAttachmentState             mAttachementNoBlendState {};
+};
+
+/*********************************************************************
+ * Class Pipeline
+ *
+ */
+
+PipelineRef Pipeline::New( Graphics& graphics, const vk::GraphicsPipelineCreateInfo& info )
+{
+  auto pipeline = Handle<Pipeline>( new Pipeline(graphics, info) );
+  graphics.AddPipeline(pipeline);
+  return pipeline;
+}
+
+Pipeline::~Pipeline() = default;
+
+Pipeline::Pipeline( Graphics& graphics, const vk::GraphicsPipelineCreateInfo& info )
+{
+  mImpl = MakeUnique<Pipeline::Impl>( graphics, info );
+}
+
+vk::Pipeline Pipeline::GetVkPipeline() const
+{
+  return mImpl->GetVkPipeline();
+}
+
+bool Pipeline::OnDestroy()
+{
+  return false;
+}
+
+void Pipeline::SetViewport( float x, float y, float width, float height )
+{
+  mImpl->SetViewport( x, y, width, height );
+}
+
+bool Pipeline::SetShader( ShaderRef shader, Shader::Type stage )
+{
+  return mImpl->SetShader( shader, stage );
+}
+
+void Pipeline::SetVertexInputState(std::vector<vk::VertexInputAttributeDescription> attrDesc,
+                         std::vector<vk::VertexInputBindingDescription> bindingDesc)
+{
+  mImpl->SetVertexInputState( attrDesc, bindingDesc );
+}
+
+void Pipeline::SetInputAssemblyState( vk::PrimitiveTopology topology, bool restartEnable )
+{
+  mImpl->SetInputAssemblyState( topology, restartEnable );
+}
+
+bool Pipeline::Compile()
+{
+  return mImpl->Compile();
+}
+
+vk::PipelineLayout Pipeline::GetVkPipelineLayout() const
+{
+  return mImpl->mPipelineLayout;
+}
+
+} // namespace Vulkan
+
+} // namespace Graphics
+
+} // namespace Dali
\ No newline at end of file
diff --git a/dali/graphics/vulkan/vulkan-pipeline.h b/dali/graphics/vulkan/vulkan-pipeline.h
new file mode 100644 (file)
index 0000000..0dbef6f
--- /dev/null
@@ -0,0 +1,119 @@
+#ifndef DALI_GRAPHICS_VULKAN_PIPELINE
+#define DALI_GRAPHICS_VULKAN_PIPELINE
+
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/graphics/vulkan/vulkan-types.h>
+#include <dali/graphics/vulkan/vulkan-shader.h>
+
+namespace Dali
+{
+namespace Graphics
+{
+namespace Vulkan
+{
+class Graphics;
+class Pipeline : public VkManaged
+{
+public:
+
+  /**
+   * Creates immutable Pipeline object ( verified resources for tracking )
+   * @param graphics
+   * @param info
+   * @return
+   */
+  static Handle<Pipeline> New( Graphics& graphics, const vk::GraphicsPipelineCreateInfo& info );
+
+  /**
+   * Destructor
+   */
+  ~Pipeline() override;
+
+  /**
+   * Sets the viewport
+   * @param x
+   * @param y
+   * @param width
+   * @param height
+   */
+  void SetViewport( float x, float y, float width, float height );
+
+  /**
+   * Attaches A shader module to the particular stage of pipeline
+   * @param shader
+   * @param stage
+   * @return
+   */
+  bool SetShader( ShaderRef shader, Shader::Type stage );
+
+  /**
+   *
+   * @param attrDesc
+   * @param bindingDesc
+   */
+  void SetVertexInputState(std::vector<vk::VertexInputAttributeDescription> attrDesc,
+                           std::vector<vk::VertexInputBindingDescription> bindingDesc);
+
+  /**
+   *
+   * @param topology
+   * @param restartEnable
+   */
+  void SetInputAssemblyState( vk::PrimitiveTopology topology, bool restartEnable );
+  /**
+   *
+   * @return
+   */
+  bool Compile();
+
+private:
+
+  Pipeline( Graphics& graphics, const vk::GraphicsPipelineCreateInfo& info );
+
+public:
+
+  /**
+   * Returns Vulkan VkPipeline object associated with Pipeline
+   * @return
+   */
+  vk::Pipeline GetVkPipeline() const;
+
+  /**
+   * Returns Vulkan VkPipelineLayout object associated with Pipeline
+   * @return
+   */
+  vk::PipelineLayout GetVkPipelineLayout() const;
+
+  bool OnDestroy() override;
+
+private:
+  class Impl;
+  std::unique_ptr<Impl> mImpl;
+};
+
+using PipelineRef = Handle<Pipeline>;
+
+} // Namespace Vulkan
+
+} // Namespace Graphics
+
+} // Namespace Dali
+
+#endif // DALI_GRAPHICS_VULKAN_PIPELINE
index 81c7a3c..fa7417b 100644 (file)
@@ -56,20 +56,20 @@ inline PrepareSemaphoresData PrepareSemaphores(const std::vector< CommandBufferR
   PrepareSemaphoresData retval{};
   for(auto& cmdbufref : commandBuffers)
   {
-    auto& cmdbuf = cmdbufref.get();
+    auto& cmdbuf = cmdbufref;
     if(!retval.signalSemaphores.empty())
     {
       retval.signalSemaphores.insert(retval.signalSemaphores.end(),
-                                     cmdbuf.GetSignalSemaphores().begin(),
-                                     cmdbuf.GetSignalSemaphores().end());
+                                     cmdbuf->GetSignalSemaphores().begin(),
+                                     cmdbuf->GetSignalSemaphores().end());
     }
     if(!retval.waitSemaphores.empty())
     {
-      retval.waitSemaphores.insert(retval.waitSemaphores.end(), cmdbuf.GetSWaitSemaphores().begin(),
-                                   cmdbuf.GetSWaitSemaphores().end());
+      retval.waitSemaphores.insert(retval.waitSemaphores.end(), cmdbuf->GetSWaitSemaphores().begin(),
+                                   cmdbuf->GetSWaitSemaphores().end());
       retval.waitDstStageMasks.insert(retval.waitDstStageMasks.end(),
-                                      cmdbuf.GetWaitSemaphoreStages().begin(),
-                                      cmdbuf.GetWaitSemaphoreStages().end());
+                                      cmdbuf->GetWaitSemaphoreStages().begin(),
+                                      cmdbuf->GetWaitSemaphoreStages().end());
     }
   }
   return std::move(retval);
@@ -77,13 +77,13 @@ inline PrepareSemaphoresData PrepareSemaphores(const std::vector< CommandBufferR
 }
 
 // submission
-Submission::Submission(Fence& fence) : mFences(fence)
+Submission::Submission(Handle<Fence> fence) : mFences(fence)
 {
 }
 
 bool Submission::WaitForFence(uint32_t timeout)
 {
-  return mFences.get().Wait(timeout);
+  return mFences->Wait(timeout);
 }
 
 // queue
@@ -97,7 +97,7 @@ Queue::~Queue() // queues are non-destructible
 {
 }
 
-std::unique_ptr< Submission > Queue::Submit(CommandBuffer& commandBuffer, Fence& fence)
+std::unique_ptr< Submission > Queue::Submit( CommandBufferRef commandBuffer, Handle<Fence> fence)
 {
   auto buffers = std::vector< CommandBufferRef >({commandBuffer});
   return Submit(buffers, fence);
@@ -105,7 +105,7 @@ std::unique_ptr< Submission > Queue::Submit(CommandBuffer& commandBuffer, Fence&
 
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wframe-larger-than="
-std::unique_ptr< Submission > Queue::Submit(const std::vector< CommandBufferRef >& commandBuffers, Fence& fence)
+std::unique_ptr< Submission > Queue::Submit(const std::vector< CommandBufferRef >& commandBuffers, Handle<Fence> fence)
 {
   // Prepare command buffers for submission
   auto buffers = PrepareBuffers(commandBuffers);
@@ -123,7 +123,7 @@ std::unique_ptr< Submission > Queue::Submit(const std::vector< CommandBufferRef
   info.setPWaitSemaphores(semaphores.waitSemaphores.data());
   info.setPWaitDstStageMask(semaphores.waitDstStageMasks.data());
 
-  VkAssert(mQueue.submit(1, &info, fence.GetFence()));
+  VkAssert(mQueue.submit(1, &info, fence->GetFence()));
 
   return MakeUnique< Submission >(fence);
 }
@@ -134,7 +134,7 @@ std::vector< vk::CommandBuffer > Queue::PrepareBuffers(const std::vector< Comman
   std::vector< vk::CommandBuffer > retval(commandBuffers.size());
   for(uint32_t i = 0; i < commandBuffers.size(); ++i)
   {
-    retval[i] = commandBuffers[i].get().Get();
+    retval[i] = commandBuffers[i]->GetVkCommandBuffer();
   }
   return retval;
 }
index 351a9fb..22c019d 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef DALI_GRAPHICS_VULKAN_QUEUE_H
-#define DALI_GRAPHICS_VULKAN_QUEUE_H
+#ifndef DALI_GRAPHICS_VULKAN_QUEUE
+#define DALI_GRAPHICS_VULKAN_QUEUE
 
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -32,13 +32,13 @@ class Fence;
 class Submission
 {
 public:
-  Submission(Fence& fence);
+  Submission(Handle<Fence> fence);
 
   bool WaitForFence(uint32_t timeout = 0u);
 
 private:
   // todo: possibly resources locks stored here?
-  FenceRef mFences;
+  Handle<Fence> mFences;
 };
 
 class Queue
@@ -51,10 +51,10 @@ public:
 
   /** Submits command buffers */
   std::unique_ptr< Submission > Submit(const std::vector< CommandBufferRef >& commandBuffers,
-                                       Fence&                                 fence);
+                                       Handle<Fence>                                 fence);
 
   /** Helper function to submit single command buffer */
-  std::unique_ptr< Submission > Submit(CommandBuffer& commandBuffer, Fence& fence);
+  std::unique_ptr< Submission > Submit(CommandBufferRef commandBuffer, Handle<Fence> fence);
 
   void WaitIdle() const;
 
@@ -89,7 +89,9 @@ private:
 };
 
 } // namespace Vulkan
+
 } // namespace Graphics
+
 } // namespace Dali
 
-#endif // DALI_GRAPHICS_VULKAN_QUEUE_H
+#endif // DALI_GRAPHICS_VULKAN_QUEUE
diff --git a/dali/graphics/vulkan/vulkan-shader.cpp b/dali/graphics/vulkan/vulkan-shader.cpp
new file mode 100644 (file)
index 0000000..fa96b2f
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <dali/graphics/vulkan/vulkan-shader.h>
+#include <dali/graphics/vulkan/vulkan-graphics.h>
+
+namespace Dali
+{
+namespace Graphics
+{
+namespace Vulkan
+{
+
+/*
+ * Class: Shader::Impl
+ */
+struct Shader::Impl
+{
+  Impl( Shader& owner, Graphics& graphics, const vk::ShaderModuleCreateInfo& info ) :
+    mOwner( owner ),
+    mGraphics( graphics ),
+    mCreateInfo( info )
+  {
+  }
+
+  ~Impl()
+  {
+    if(mDSLayouts.size())
+    {
+      for(auto&& ds : mDSLayouts )
+      {
+        mGraphics.GetDevice().destroyDescriptorSetLayout( ds, mGraphics.GetAllocator() );
+      }
+    }
+    if(mShaderModule)
+    {
+      mGraphics.GetDevice().destroyShaderModule( mShaderModule, mGraphics.GetAllocator() );
+    }
+  }
+
+  vk::Result Initialise()
+  {
+    if( (mShaderModule = VkAssert( mGraphics.GetDevice().createShaderModule( mCreateInfo, mGraphics.GetAllocator() ) )))
+    {
+      return vk::Result::eSuccess;
+    }
+    return vk::Result::eErrorInitializationFailed;
+  }
+
+  vk::ShaderModule GetVkShaderModule() const
+  {
+    return mShaderModule;
+  }
+
+
+  // creates new descriptor set layout
+  // TODO: should be read from the shader and any manual setting should not
+  // take place after we have proper reflection!
+  void SetDescriptorSetLayout( uint32_t set, vk::DescriptorSetLayoutCreateInfo info )
+  {
+    auto layout = VkAssert( mGraphics.GetDevice().createDescriptorSetLayout( info, mGraphics.GetAllocator() ) );
+    if( mDSLayouts.size() >= set )
+    {
+      mDSLayouts.resize( set+1 );
+    }
+    else if ( mDSLayouts[set] ) // already existing set ( this is error but for now handle it )
+    {
+      mGraphics.GetDevice().destroyDescriptorSetLayout( mDSLayouts[set], mGraphics.GetAllocator() );
+    }
+    mDSLayouts[set] = layout;
+  }
+
+  const std::vector<vk::DescriptorSetLayout>& GetDescriptorSetLayouts() const
+  {
+    return mDSLayouts;
+  }
+
+
+  Shader& mOwner;
+  Graphics& mGraphics;
+  vk::ShaderModuleCreateInfo mCreateInfo;
+  vk::ShaderModule mShaderModule;
+  std::vector<vk::DescriptorSetLayout> mDSLayouts; // descriptorset layouts
+};
+
+/*
+ * Class: Shader
+ */
+Handle<Shader> Shader::New(Graphics &graphics, const vk::ShaderModuleCreateInfo &info)
+{
+  auto shader = Handle<Shader>(new Shader(graphics, info)); // can't use make unique because of permissions
+  if(shader)
+  {
+    if( shader->mImpl->Initialise() == vk::Result::eSuccess )
+    {
+      graphics.AddShader( shader );
+    }
+  }
+  return shader;
+}
+
+Handle<Shader> Shader::New( Graphics& graphics, const void* bytes, std::size_t size )
+{
+  return New( graphics, vk::ShaderModuleCreateInfo{}
+                                .setCodeSize( size )
+                                .setPCode(reinterpret_cast<const uint32_t*>(bytes)));
+}
+
+Shader::Shader( Graphics& graphics, const vk::ShaderModuleCreateInfo& info )
+{
+  mImpl = MakeUnique<Impl>( *this, graphics, info );
+}
+
+Shader::~Shader() = default;
+
+vk::ShaderModule Shader::GetVkShaderModule() const
+{
+  return mImpl->GetVkShaderModule();
+}
+
+bool Shader::OnDestroy()
+{
+  mImpl->mGraphics.RemoveShader( *this );
+  return true;
+}
+
+void Shader::SetDescriptorSetLayout( uint32_t set, vk::DescriptorSetLayoutCreateInfo info )
+{
+  mImpl->SetDescriptorSetLayout( set, info );
+}
+
+const std::vector<vk::DescriptorSetLayout>& Shader::GetDescriptorSetLayouts() const
+{
+  return mImpl->GetDescriptorSetLayouts();
+}
+}
+}
+}
\ No newline at end of file
diff --git a/dali/graphics/vulkan/vulkan-shader.h b/dali/graphics/vulkan/vulkan-shader.h
new file mode 100644 (file)
index 0000000..1c0a997
--- /dev/null
@@ -0,0 +1,98 @@
+#ifndef DALI_GRAPHICS_VULKAN_SHADER
+#define DALI_GRAPHICS_VULKAN_SHADER
+
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/graphics/vulkan/vulkan-types.h>
+
+namespace Dali
+{
+namespace Graphics
+{
+namespace Vulkan
+{
+class Graphics;
+class Shader : public VkManaged // can be overriden as ShaderGLSL for example
+{
+public:
+
+  enum class Type
+  {
+    VERTEX = static_cast<int>( vk::ShaderStageFlagBits::eVertex ),
+    FRAGMENT = static_cast<int>( vk::ShaderStageFlagBits::eFragment ),
+    COMPUTE = static_cast<int>( vk::ShaderStageFlagBits::eCompute ),
+    GEOMETRY = static_cast<int>( vk::ShaderStageFlagBits::eGeometry ),
+  };
+
+  /**
+   *
+   * @param graphics
+   * @param info
+   * @return
+   */
+  static Handle<Shader> New( Graphics& graphics, const vk::ShaderModuleCreateInfo& info );
+
+  /**
+   * Creates new shader module from SPIRV code
+   * @param graphics
+   * @param bytes
+   * @param size
+   * @return
+   */
+  static Handle<Shader> New( Graphics& graphics, const void* bytes, std::size_t size );
+
+  /**
+   *
+   */
+  ~Shader();
+
+  vk::ShaderModule GetVkShaderModule() const;
+
+  const std::vector<vk::DescriptorSetLayout>& GetDescriptorSetLayouts() const;
+
+  bool OnDestroy() override;
+
+  operator vk::ShaderModule() const
+  {
+    return GetVkShaderModule();
+  }
+
+public:
+
+  void SetDescriptorSetLayout( uint32_t set, vk::DescriptorSetLayoutCreateInfo info );
+
+private:
+
+  Shader( Graphics& graphics, const vk::ShaderModuleCreateInfo& info );
+
+private:
+
+  class Impl;
+  std::unique_ptr<Impl> mImpl;
+};
+
+using ShaderRef = Handle<Shader>;
+
+} // Namespace Vulkan
+
+} // Namespace Graphics
+
+} // Namespace Dali
+
+#endif // DALI_GRAPHICS_VULKAN_SHADER
index f42b323..ff62bb0 100644 (file)
 #define VK_USE_PLATFORM_XCB_KHR
 #endif
 
+#include <glm/glm.hpp>
+#include <glm/matrix.hpp>
+#include <glm/vector_relational.hpp>
+#include <glm/gtc/matrix_transform.hpp>
+
+using namespace glm;
+
 #include <dali/integration-api/graphics/vulkan/vulkan-hpp-wrapper.h>
 
 #include <dali/integration-api/graphics/vulkan/vk-surface-factory.h>
 #include <xcb/xcb.h>
 #include <unistd.h>
 
+// internals
+#include <dali/graphics/vulkan/vulkan-buffer.h>
+#include <dali/graphics/vulkan/vulkan-graphics.h>
+#include <dali/graphics/vulkan/gpu-memory/vulkan-gpu-memory-manager.h>
+#include <dali/graphics/vulkan/vulkan-shader.h>
+#include <dali/graphics/vulkan/vulkan-descriptor-set.h>
+#include <dali/graphics/vulkan/gpu-memory/vulkan-gpu-memory-manager.h>
+#include <dali/graphics/vulkan/gpu-memory/vulkan-gpu-memory-allocator.h>
+#include <dali/graphics/vulkan/gpu-memory/vulkan-gpu-memory-handle.h>
+#include <dali/graphics/vulkan/vulkan-pipeline.h>
+#include <dali/graphics/vulkan/vulkan-command-pool.h>
+#include <dali/graphics/vulkan/vulkan-command-buffer.h>
+#include <dali/graphics/vulkan/vulkan-surface.h>
+#include <dali/graphics/vulkan/vulkan-descriptor-set.h>
+
+#include "generated/spv-shaders-gen.h"
+
 #define USE_XLIB 0
+#include <iostream>
 
 using Dali::Integration::Graphics::Graphics;
 using Dali::Integration::Graphics::Vulkan::VkSurfaceFactory;
+using Dali::Graphics::Vulkan::Buffer;
+using Dali::Graphics::Vulkan::DeviceMemory;
+using Dali::Graphics::Vulkan::Shader;
+using Dali::Graphics::Vulkan::DescriptorSetLayout;
+using Dali::Graphics::Vulkan::GpuMemoryManager;
+using Dali::Graphics::Vulkan::GpuMemoryAllocator;
+using Dali::Graphics::Vulkan::Shader;
+using Dali::Graphics::Vulkan::ShaderRef;
+using Dali::Graphics::Vulkan::Pipeline;
+using Dali::Graphics::Vulkan::PipelineRef;
+using Dali::Graphics::Vulkan::CommandPool;
+using Dali::Graphics::Vulkan::CommandBuffer;
+using Dali::Graphics::Vulkan::DescriptorPool;
+
+extern std::vector<uint8_t> VSH;
+extern std::vector<uint8_t> FSH;
 
 template< typename T, typename... Args >
 std::unique_ptr< T > MakeUnique(Args&&... args)
@@ -176,6 +217,156 @@ std::unique_ptr< Test::xcb_window_t > create_xcb_window(int width, int height)
 
 namespace VulkanTest
 {
+
+Dali::Graphics::Vulkan::GpuMemoryBlockHandle test_gpu_memory_manager( Dali::Graphics::Vulkan::Graphics& graphics,
+                                         GpuMemoryManager& gpuManager,
+                                         const Dali::Graphics::Vulkan::Handle<Buffer>& buffer )
+{
+  auto device = graphics.GetDevice();
+  auto& allocator = graphics.GetAllocator();
+
+  auto& gpuAllocator = gpuManager.GetDefaultAllocator();
+  return gpuAllocator.Allocate( buffer, vk::MemoryPropertyFlagBits::eHostVisible );
+}
+
+struct UniformData
+{
+  mat4 modelMat;
+  mat4 viewMat;
+  mat4 projMat;
+  vec4 color;
+} __attribute__((aligned(16)));
+
+
+mat4 MVP;
+
+
+
+
+template <class T>
+void update_buffer( Dali::Graphics::Vulkan::BufferHandle buffer, T& value )
+{
+  auto ptr = reinterpret_cast<T*>(buffer->GetMemoryHandle()->Map());
+  *ptr = value;
+  buffer->GetMemoryHandle()->Unmap();
+}
+
+void update_translation( Dali::Graphics::Vulkan::BufferHandle buffer )
+{
+  static float x = 0.0f;
+  x += 0.5f;
+
+  UniformData ub;
+  ub.modelMat = mat4{1.0f};
+  ub.modelMat = glm::translate( ub.modelMat, vec3( x, x, 0.0f ));
+  ub.modelMat = glm::rotate( ub.modelMat, glm::radians( x ), glm::vec3( 0.0f, 0.0f, 1.0f) );
+  ub.viewMat = lookAt( vec3( 0.0f, 0.0f, 10.0f ),
+                        vec3( 0.0f, 0.0f, 0.0f ),
+                        vec3( 0.0f, 1.0f, 0.0f ) );
+
+  glm::mat4 clip( 1.0f, 0.0f, 0.0f, 0.0f,
+                  0.0f, -1.0f, 0.0f, 0.0f,
+                  0.0f, 0.0f, 0.5f, 0.0f,
+                  0.0f, 0.0f, 0.5f, 1.0f );
+
+  ub.projMat = clip * ortho( 0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 100.0f );
+  ub.color = vec4( x / 640.0f, x / 480.0f, 1.0f, 1.0f );
+  update_buffer( buffer, ub );
+}
+
+Dali::Graphics::Vulkan::BufferHandle create_uniform_buffer( Dali::Graphics::Vulkan::Graphics& gr )
+{
+  // create uniform buffer
+  auto uniformBuffer = Buffer::New( gr, sizeof(UniformData), Buffer::Type::UNIFORM );
+
+  // allocate memory
+  auto memory = gr.GetDeviceMemoryManager().GetDefaultAllocator().Allocate( uniformBuffer, vk::MemoryPropertyFlagBits::eHostVisible );
+
+  // bind memory
+  uniformBuffer->BindMemory( memory );
+
+  auto ub = reinterpret_cast<UniformData*>(memory->Map());
+
+  ub->modelMat = mat4{1.0f};
+  //ub->modelMat = glm::translate( ub->modelMat, vec3( 0.0f, 0.0f, 0.0f ));
+
+  ub->viewMat = lookAt( vec3( 0.0f, 0.0f, 10.0f ),
+                        vec3( 0.0f, 0.0f, 0.0f ),
+                        vec3( 0.0f, 1.0f, 0.0f ) );
+
+  glm::mat4 clip( 1.0f, 0.0f, 0.0f, 0.0f,
+                  0.0f, -1.0f, 0.0f, 0.0f,
+                  0.0f, 0.0f, 0.5f, 0.0f,
+                  0.0f, 0.0f, 0.5f, 1.0f );
+
+  ub->projMat = clip * ortho( 0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 100.0f );
+  ub->color = vec4( 0.0f, 1.0f, 1.0f, 1.0f );
+
+
+  MVP = ub->projMat * ub->viewMat * ub->modelMat;
+
+  memory->Unmap();
+
+  return uniformBuffer;
+}
+
+Dali::Graphics::Vulkan::Handle<DescriptorPool>
+create_descriptor_pool( Dali::Graphics::Vulkan::Graphics& gr )
+{
+  vk::DescriptorPoolSize size;
+  size.setDescriptorCount( 1024 ).setType( vk::DescriptorType::eUniformBuffer );
+
+  // TODO: how to organize this???
+  auto pool = DescriptorPool::New( gr,
+    vk::DescriptorPoolCreateInfo{}.
+      setMaxSets( 1024 ).
+      setPoolSizeCount(1).setPPoolSizes(&size));
+  return pool;
+}
+
+void test_handle()
+{
+  /*
+  using namespace Dali::Graphics::Vulkan;
+  GpuMemoryBlockHandle handle( new GpuMemoryBlock() );
+
+  decltype(handle) handle2 = handle;
+  handle.GetRefCount();*/
+}
+
+PipelineRef
+create_pipeline( Dali::Graphics::Vulkan::Graphics& graphics,
+                      Dali::Graphics::Vulkan::ShaderRef vertexShader,
+                      Dali::Graphics::Vulkan::ShaderRef fragmentShader
+                      )
+{
+  using namespace Dali::Graphics::Vulkan;
+  auto pipelineInfo = vk::GraphicsPipelineCreateInfo{};
+  auto pipeline = Pipeline::New( graphics, pipelineInfo );
+
+  pipeline->SetShader( vertexShader, Shader::Type::VERTEX );
+  pipeline->SetShader( fragmentShader, Shader::Type::FRAGMENT );
+  pipeline->SetViewport( 0, 0, 640, 480 );
+  pipeline->SetVertexInputState(
+    std::vector<vk::VertexInputAttributeDescription>{vk::VertexInputAttributeDescription{}.
+                                           setBinding( 0 ).
+                                           setOffset( 0 ).
+                                           setLocation( 0 ).
+                                           setFormat( vk::Format::eR32G32B32Sfloat )},
+    std::vector<vk::VertexInputBindingDescription>{vk::VertexInputBindingDescription{}.
+                                           setBinding( 0 ).
+                                           setStride( sizeof(float)*3  ).
+                                           setInputRate( vk::VertexInputRate::eVertex)}
+  );
+  pipeline->SetInputAssemblyState( vk::PrimitiveTopology::eTriangleList, false );
+
+  if( !pipeline->Compile() )
+  {
+    pipeline.Reset();
+  }
+  return pipeline;
+}
+
 int RunTestMain()
 {
 
@@ -189,14 +380,113 @@ int RunTestMain()
          std::unique_ptr<VkSurfaceXcb>{new VkSurfaceXcb{window->connection, window->window}};
 #endif
 
+
   auto graphics = MakeUnique<Graphics>();
   auto fbid = graphics->Create( std::move(surfaceFactory) );
 
-  while(1)
+  // access internal implementation
+  auto& gr = graphics->GetImplementation<Dali::Graphics::Vulkan::Graphics>();
+
+  // GPU memory manager
+  auto& memmgr = gr.GetDeviceMemoryManager();
+
+  const vec3 VERTICES[] =
+          {
+            {0.0f, 0.0f, 0.0f},
+            {320.0f, 0.0f, 0.0f},
+            {0.0f, 160.0f, 0.0f},
+          };
+
+
+
+
+  // shaders
+  auto vertexShader = Shader::New( gr, VSH_CODE.data(), VSH_CODE.size() );
+  vertexShader->SetDescriptorSetLayout( 0, vk::DescriptorSetLayoutCreateInfo{}.
+    setBindingCount( 1 ).
+    setPBindings( std::vector<vk::DescriptorSetLayoutBinding>{
+                    vk::DescriptorSetLayoutBinding{}.
+                                                      setBinding( 0 ).
+                                                      setStageFlags( vk::ShaderStageFlagBits::eVertex ).
+                                                      setDescriptorType( vk::DescriptorType::eUniformBuffer ).
+                                                      setDescriptorCount( 1 )
+                  }.data()
+    ));
+
+  auto fragmentShader = Shader::New( gr, FSH_CODE.data(), FSH_CODE.size() );
+
+  // buffer
+  auto vertexBuffer = Buffer::New( gr, sizeof(float)*3*3, Buffer::Type::VERTEX );
+
+  auto descriptorPool = create_descriptor_pool( gr );
+  auto descriptorSet = descriptorPool->AllocateDescriptorSets( vk::DescriptorSetAllocateInfo{}
+  .setPSetLayouts( vertexShader->GetDescriptorSetLayouts().data() )
+  .setDescriptorSetCount( static_cast<uint32_t>(vertexShader->GetDescriptorSetLayouts().size())));
+
+
+
+  auto& gpuManager = gr.GetDeviceMemoryManager();
+
+  auto bufferMemory = test_gpu_memory_manager( gr, gpuManager, vertexBuffer );
+  vertexBuffer->BindMemory( bufferMemory );
+
+  auto ptr = static_cast<uint8_t*>(bufferMemory->Map());
+  std::copy( reinterpret_cast<const uint8_t*>(VERTICES), reinterpret_cast<const uint8_t*>(VERTICES)+(sizeof(float)*9), ptr);
+  bufferMemory->Unmap();
+
+  auto pipeline = create_pipeline( gr, vertexShader, fragmentShader );
+
+  auto commandPool = CommandPool::New( gr );
+
+  auto uniformBuffer = create_uniform_buffer( gr );
+
+  descriptorSet[0]->WriteUniformBuffer( 0, uniformBuffer, 0, uniformBuffer->GetSize() );
+
+  // get new buffer
+  auto cmdDraw = commandPool->NewCommandBuffer( false );
+
+  // begin recording
+  cmdDraw->Begin( vk::CommandBufferUsageFlagBits::eRenderPassContinue);
+
+  // vertex buffer
+  cmdDraw->BindVertexBuffer( 0, vertexBuffer, 0 );
+
+  // pipeline
+  cmdDraw->BindGraphicsPipeline( pipeline );
+
+  // descriptor sets
+  cmdDraw->BindDescriptorSets( descriptorSet, 0 );
+
+  // do draw
+  cmdDraw->Draw( 3, 1, 0, 0 );
+
+  // finish
+  cmdDraw->End();
+
+
+
+  bool running = true;
+
+  while( running )
   {
     graphics->PreRender( fbid );
+    // queue submit draw
+
+    auto cmdbuf = gr.GetSurface( fbid ).GetCurrentCommandBuffer();
+
+    // get command buffer for current frame and execute the draw call
+    cmdbuf->ExecuteCommands( { cmdDraw } );
+
+
     graphics->PostRender( fbid );
+
+    update_translation( uniformBuffer );
   }
   return 0;
 }
 }
+
+int main()
+{
+  VulkanTest::RunTestMain();
+}
index 6d047a9..c38377a 100644 (file)
@@ -73,7 +73,7 @@ void Surface::AcquireNextImage()
 
   if(!mFrameFence)
   {
-    mFrameFence = MakeUnique< Fence >(mGraphics);
+    mFrameFence = Fence::New(mGraphics);
   }
 
   // acquire image, for simplicity using fence for acquiring as it is unknown what next command buffer will
@@ -92,7 +92,7 @@ void Surface::AcquireNextImage()
   if(swapImage.layout != vk::ImageLayout::eColorAttachmentOptimal)
   {
     auto& queue = mGraphics.GetGraphicsQueue();
-    queue.Submit(*swapImage.layoutToColorCmdBuf.get(), *mFrameFence.get())->WaitForFence();
+    queue.Submit(swapImage.layoutToColorCmdBuf, mFrameFence)->WaitForFence();
   }
 
   mFrameFence->Reset();
@@ -112,16 +112,16 @@ void Surface::BeginRenderPass()
    * todo: automatically start main render pass -> this may have to be done manually in future
    * if more flexibility is needed
    */
-  auto vkCmdBuf = swapImage.mainCmdBuf->Get();
+  auto vkCmdBuf = swapImage.mainCmdBuf->GetVkCommandBuffer();
   {
     std::array< vk::ClearValue, 2 > clearValues;
 
-    static float r = 0.0f;
-    r += 0.01f;
+    static float r = 1.0f;
+    //r += 0.01f;
     if(r > 1.0f)
       r -= 1.0f;
 
-    clearValues[0].color.setFloat32({r, 0.0f, 0.0f, 1.0f});
+    clearValues[0].color.setFloat32({0.0f, 1.0f, 0.0f, 1.0f});
     clearValues[1].depthStencil.setDepth(1.0f).setStencil(0.0f);
 
     auto rpInfo = vk::RenderPassBeginInfo{};
@@ -131,16 +131,51 @@ void Surface::BeginRenderPass()
         .setClearValueCount(mHasDepthStencil ? 2 : 1)
         .setPClearValues(clearValues.data());
 
-    auto subpassContents = vk::SubpassContents{vk::SubpassContents::eInline};
+    auto subpassContents = vk::SubpassContents{vk::SubpassContents::eSecondaryCommandBuffers};
     vkCmdBuf.beginRenderPass(rpInfo, subpassContents);
   }
 }
 
+std::vector<vk::ClearValue> Surface::GetClearValues() const
+{
+  static float r = 0.0f;
+  r += 0.01f;
+  if(r > 1.0f)
+    r -= 1.0f;
+
+  std::array< vk::ClearValue, 2 > clearValues;
+  clearValues[0].color.setFloat32({r, 0.0f, 0.0f, 1.0f});
+  clearValues[1].depthStencil.setDepth(1.0f).setStencil(0.0f);
+
+  auto retval = std::vector<vk::ClearValue>{};
+  retval.emplace_back( clearValues[0] );
+  if( mHasDepthStencil )
+  {
+    retval.emplace_back( clearValues[1] );
+  }
+  return retval;
+}
+
+vk::Extent2D Surface::GetSize() const
+{
+  return mCapabilities->currentExtent;
+}
+
+Handle<CommandBuffer> Surface::GetCommandBuffer( uint32_t index )
+{
+  return mSwapImages[index].mainCmdBuf;
+}
+
+Handle<CommandBuffer> Surface::GetCurrentCommandBuffer()
+{
+  return mSwapImages[mCurrentBufferIndex].mainCmdBuf;
+}
+
 void Surface::EndRenderPass()
 {
   // todo: use semaphores and do not create fences all over again
   auto& swapImage = mSwapImages[mCurrentBufferIndex];
-  auto  vkCmdBuf  = swapImage.mainCmdBuf->Get();
+  auto  vkCmdBuf  = swapImage.mainCmdBuf->GetVkCommandBuffer();
 
   // complete render pass
   vkCmdBuf.endRenderPass();
@@ -150,7 +185,7 @@ void Surface::EndRenderPass()
 
   // submit
   auto& queue = mGraphics.GetGraphicsQueue();
-  queue.Submit(*swapImage.mainCmdBuf.get(), *mFrameFence.get())->WaitForFence();
+  queue.Submit(swapImage.mainCmdBuf, mFrameFence)->WaitForFence();
 }
 
 void Surface::Present()
@@ -260,7 +295,7 @@ void Surface::InitialiseSwapchain()
 void Surface::AddSwapchainImage(vk::Image image, std::vector< SwapchainImage >& swapchainImages)
 {
   auto swapImage  = std::move(SwapchainImage{});
-  swapImage.image = MakeUnique<Image>( mGraphics, image );
+  swapImage.image = MakeRef<Image>( mGraphics, image );
 
   // create ImageView
   CreateImageView(swapImage);
@@ -379,9 +414,7 @@ void Surface::CreateCommandBuffers()
 {
   if(!mCommandPool)
   {
-    auto info = vk::CommandPoolCreateInfo{}.setFlags(vk::CommandPoolCreateFlagBits::eResetCommandBuffer);
-    info.setQueueFamilyIndex(0); // todo: get correct queue family index ( 0 works by default ;) )
-    mCommandPool = MakeUnique< CommandPool >(mGraphics, info);
+    mCommandPool = CommandPool::New( mGraphics, vk::CommandPoolCreateInfo{}.setFlags(vk::CommandPoolCreateFlagBits::eResetCommandBuffer) );
   }
 
   // allocate command buffers
@@ -391,8 +424,8 @@ void Surface::CreateCommandBuffers()
 
   for(auto& swapImage : mSwapImages)
   {
-    swapImage.layoutToColorCmdBuf = mCommandPool->AllocateCommandBuffer(cmdInfo);
-    swapImage.mainCmdBuf          = mCommandPool->AllocateCommandBuffer(cmdInfo);
+    swapImage.layoutToColorCmdBuf = mCommandPool->NewCommandBuffer(cmdInfo);
+    swapImage.mainCmdBuf          = mCommandPool->NewCommandBuffer(cmdInfo);
 
     // Record layout transition for each image, after transition command buffers will be re-recorded
     // and will take in account only present -> color layout transition
@@ -404,13 +437,13 @@ void Surface::CreateCommandBuffers()
     swapImage.layoutToColorCmdBuf->End();
     swapImage.layout = vk::ImageLayout::eColorAttachmentOptimal;
 
-    cmdBuffers.push_back(std::ref(*swapImage.layoutToColorCmdBuf.get()));
+    cmdBuffers.push_back(swapImage.layoutToColorCmdBuf);
   }
 
   // submit to the queue
   {
     auto& queue      = mGraphics.GetGraphicsQueue();
-    auto  fence      = Fence(mGraphics);
+    auto  fence      = Fence::New(mGraphics);
     auto  submission = queue.Submit(cmdBuffers, fence);
     submission->WaitForFence();
   }
index c45d2d5..9ffdc92 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef DALI_GRAPHICS_VULKAN_SURFACE_H
-#define DALI_GRAPHICS_VULKAN_SURFACE_H
+#ifndef DALI_GRAPHICS_VULKAN_SURFACE
+#define DALI_GRAPHICS_VULKAN_SURFACE
 
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -53,16 +53,16 @@ struct SwapchainImage
   SwapchainImage& operator=(const SwapchainImage&) = delete;
   SwapchainImage& operator=(SwapchainImage&&) = default;
 
-  UniqueImage     image;
-  UniqueImageView imageView;
+  ImageRef        image;
+  ImageViewRef    imageView;
   vk::Framebuffer framebuffer;
   vk::ImageLayout layout;
   vk::Semaphore   acqSem;
   vk::Semaphore   presentSem;
 
   // layout transitions, prerecorded command buffers
-  UniqueCommandBuffer layoutToColorCmdBuf;
-  UniqueCommandBuffer mainCmdBuf;
+  Handle<CommandBuffer> layoutToColorCmdBuf;
+  Handle<CommandBuffer> mainCmdBuf;
 };
 
 class Surface
@@ -115,9 +115,38 @@ public:
    */
   vk::SurfaceKHR GetSurfaceKHR() const;
 
-private:
+  /**
+   * returns set of clear values for this surface
+   * @return
+   */
+  std::vector<vk::ClearValue> GetClearValues() const;
+
+  /**
+   * Returns size of surface
+   * @return
+   */
+  vk::Extent2D GetSize() const;
+
+  /**
+   * Returns primary command buffer associated with specific buffer
+   * @param index
+   * @return
+   */
+  Handle<CommandBuffer> GetCommandBuffer( uint32_t index );
+
+  /**
+   * Returns primary command buffer associated with current buffer
+   * @return
+   */
+  Handle<CommandBuffer> GetCurrentCommandBuffer();
+
+/**
+   *
+   */
   void CreateSwapchain();
 
+private:
+
   void CreateVulkanSwapchain();
 
   void CreateImageView(SwapchainImage& swapImage);
@@ -151,7 +180,7 @@ private:
   vk::ImageView    mDepthStencilImageView;
   vk::DeviceMemory mDepthStencilMemory;
 
-  UniqueCommandPool mCommandPool;
+  Handle<CommandPool> mCommandPool;
 
   vk::Format        mFormat;
   vk::ColorSpaceKHR mColorSpace;
@@ -160,7 +189,7 @@ private:
   std::vector< SwapchainImage >                 mSwapImages;
   std::unique_ptr< vk::SurfaceCapabilitiesKHR > mCapabilities;
 
-  UniqueFence mFrameFence;
+  Handle<Fence>   mFrameFence;
 
   vk::RenderPass mDefaultRenderPass;
   uint32_t       mBufferCount;
@@ -172,4 +201,4 @@ private:
 } // namespace Graphics
 } // namespace Dali
 
-#endif // DALI_GRAPHICS_VULKAN_SURFACE_H
+#endif // DALI_GRAPHICS_VULKAN_SURFACE
index 255c549..9ccc269 100644 (file)
@@ -1,8 +1,8 @@
-#ifndef DALI_GRAPHICS_VULKAN_TYPES_H
-#define DALI_GRAPHICS_VULKAN_TYPES_H
+#ifndef DALI_GRAPHICS_VULKAN_TYPES
+#define DALI_GRAPHICS_VULKAN_TYPES
 
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -33,7 +33,7 @@ namespace Graphics
 template< typename T, typename... Args >
 std::unique_ptr< T > MakeUnique(Args&&... args)
 {
-  return std::unique_ptr< T >(new T(std::forward< Args >(args)...));
+  return std::unique_ptr< T  >(new T(std::forward< Args >(args)...));
 }
 
 namespace Vulkan
@@ -43,39 +43,22 @@ namespace Vulkan
  * Forward class declarations
  */
 class Graphics;
-class CommandBuffer;
-class CommandPool;
 class Surface;
 class Queue;
-class Fence;
-class DeviceMemory;
-class Image;
-class ImageView;
-class Buffer;
 
 /**
  * Unique pointers to Vulkan types
  */
 using UniqueSurface       = std::unique_ptr< Surface >;
-using UniqueCommandBuffer = std::unique_ptr< CommandBuffer >;
-using UniqueCommandPool   = std::unique_ptr< CommandPool >;
 using UniqueQueue         = std::unique_ptr< Queue >;
-using UniqueFence         = std::unique_ptr< Fence >;
-using UniqueDeviceMemory  = std::unique_ptr< DeviceMemory >;
-using UniqueBuffer        = std::unique_ptr< Buffer >;
-using UniqueImage         = std::unique_ptr< Image >;
-using UniqueImageView     = std::unique_ptr< ImageView >;
 
 /**
  * Reference wrappers
  */
-using CommandBufferRef = std::reference_wrapper< CommandBuffer >;
 using QueueRef         = std::reference_wrapper< Queue >;
-using FenceRef         = std::reference_wrapper< Fence >;
 using SurfaceRef       = std::reference_wrapper< Surface >;
 
 
-
 template< typename T >
 T VkAssert(const vk::ResultValue< T >& result, vk::Result expected = vk::Result::eSuccess)
 {
@@ -127,55 +110,204 @@ private:
   std::atomic<uint32_t> mUserCount;
 };
 
-template< typename T>
-class ResourceRef
+/**
+ * Vulkan object handle
+ * @tparam T
+ */
+template<class T>
+class Handle
 {
 public:
 
-  ResourceRef( T& object )
-  : mObject( &object )
+  Handle();
+  explicit Handle(T* object );
+  Handle( const Handle& handle);
+  Handle& operator=( const Handle& handle );
+  Handle& operator=( Handle&& handle );
+  Handle( Handle&& handle ) noexcept;
+  ~Handle();
+
+  operator bool() const;
+
+  T* operator->() const
   {
-    mObject->IncreaseUserCount();
+    return mObject;
   }
 
-  ResourceRef( ResourceRef& object )
+  uint32_t GetRefCount() const
   {
-    if(mObject)
-    {
-      mObject->DecreaseUserCount();
-    }
+    return mObject->GetRefCount();
+  }
 
-    mObject = object.mObject;
-    mObject->IncreaseUserCount();
+  T& operator*() const
+  {
+    return *mObject;
   }
 
-  ResourceRef operator=(ResourceRef& object )
+  template <class K>
+  Handle<K> StaticCast()
   {
-    if(mObject)
+    return Handle<K>(static_cast<K*>(mObject));
+  }
+
+  template<class K>
+  bool operator==( const Handle<K>& object ) const
+  {
+    return mObject == &*object;
+  }
+
+  template <class K>
+  Handle<K> DynamicCast();
+
+  void Reset()
+  {
+    if( mObject )
     {
-      mObject->DecreaseUserCount();
+      mObject->Release();
+      mObject = nullptr;
     }
+  }
 
-    mObject = object.mObject;
-    mObject->IncreaseUserCount();
+private:
+
+  T* mObject { nullptr };
+};
+
+template <class K, class T>
+static Handle<K> VkTypeCast( const Handle<T>& inval )
+{
+  return Handle<K>(static_cast<K*>(&*inval));
+}
+
+template<class T>
+Handle<T>::Handle(T* object)
+  : mObject( object )
+{
+  if(mObject)
+  {
+    mObject->Retain();
   }
+}
+
+template<class T>
+Handle<T>::Handle()
+  : mObject( nullptr )
+{
+}
 
-  ~ResourceRef()
+template<class T>
+Handle<T>::Handle(const Handle& handle)
+{
+  mObject = handle.mObject;
+  if(mObject)
   {
-    if(mObject)
+    mObject->Retain();
+  }
+}
+
+template<class T>
+Handle<T>::Handle( Handle&& handle ) noexcept
+{
+  mObject = handle.mObject;
+  handle.mObject = nullptr;
+}
+
+template<class T>
+Handle<T>::operator bool() const
+{
+  return mObject != nullptr;
+}
+
+template<class T>
+Handle<T>& Handle<T>::operator=( Handle&& handle )
+{
+  mObject = handle.mObject;
+  handle.mObject = nullptr;
+  return *this;
+}
+
+template<class T>
+Handle<T>& Handle<T>::operator=( const Handle<T>& handle )
+{
+  mObject = handle.mObject;
+  if(mObject)
+  {
+    mObject->Retain();
+  }
+  return *this;
+}
+
+template<class T>
+Handle<T>::~Handle()
+{
+  if(mObject)
+  {
+    mObject->Release();
+  }
+}
+
+template<class T>
+template<class K>
+Handle<K> Handle<T>::DynamicCast()
+{
+  auto val = dynamic_cast<K*>(mObject);
+  if(val)
+  {
+    return Handle<K>(val);
+  }
+  return Handle<K>();
+}
+
+template< typename T, typename... Args >
+Handle< T > MakeRef(Args&&... args)
+{
+  return Handle< T  >(new T(std::forward< Args >(args)...));
+}
+
+class VkManaged
+{
+public:
+
+  VkManaged() = default;
+  virtual ~VkManaged() = default;
+
+  void Release()
+  {
+    OnRelease(--mRefCount);
+    if(mRefCount == 0)
     {
-      mObject->DecreaseUserCount();
+      // orphaned
+      if(!Destroy())
+      {
+        delete this;
+      }
     }
   }
 
-  T& GetResource() const
+  void Retain()
   {
-    return *mObject;
+    OnRetain(++mRefCount);
+  }
+
+  uint32_t GetRefCount()
+  {
+    return mRefCount;
   }
 
+  bool Destroy()
+  {
+    return OnDestroy();
+  }
+
+  virtual void OnRetain( uint32_t refcount ) {};
+
+  virtual void OnRelease( uint32_t refcount ) {};
+
+  virtual bool OnDestroy() { return false; };
+
 private:
 
-  T* mObject;
+  std::atomic_uint mRefCount { 0u };
 };
 
 using FBID = uint32_t;
@@ -187,6 +319,20 @@ assert( "Function no implemented" );\
 }
 
 /*
+ * Forward declarations of reference types
+ */
+using ShaderRef = Handle<class Shader>;
+using PipelineRef = Handle<class Pipeline>;
+using FenceRef = Handle<class Fence>;
+using BufferRef = Handle<class Buffer>;
+using FramebufferRef = Handle<class Framebuffer>;
+using ImageRef = Handle<class Image>;
+using ImageViewRef = Handle<class ImageView>;
+using DescriptorPoolRef = Handle<class DescriptorPool>;
+using CommandPoolRef = Handle<class CommandPool>;
+using CommandBufferRef = Handle<class CommandBuffer>;
+
+/*
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wframe-larger-than="
 #pragma GCC diagnostic pop
@@ -195,4 +341,4 @@ assert( "Function no implemented" );\
 } // namespace Graphics
 } // namespace Dali
 
-#endif // DALI_GRAPHICS_VULKAN_TYPES_H
+#endif // DALI_GRAPHICS_VULKAN_TYPES
index 1f06c8d..9db5d47 100644 (file)
@@ -59,6 +59,9 @@ Dali::Graphics::FBID Graphics::Create(
   // create device
   mGraphicsImpl->CreateDevice();
 
+  // create swapchain
+  mGraphicsImpl->GetSurface( retval ).CreateSwapchain();
+
   return retval;
 }
 
index 1603aba..03e29e4 100644 (file)
@@ -77,11 +77,20 @@ public:
    */
   void PostRender( Dali::Graphics::FBID framebufferId = 0u );
 
+  // this function is used only by the standalone test
+  template <class T>
+  T& GetImplementation() const
+  {
+    return static_cast<T&>(*mGraphicsImpl.get());
+  }
+
 private:
 
   std::unique_ptr<Dali::Graphics::GraphicsImpl> mGraphicsImpl;
 };
 
+
+
 /**
  * fixme: dummy function to make sure the static library won't be discarded entirely during linking
  */