# 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
--- /dev/null
+#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
--- /dev/null
+// 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
+
+
--- /dev/null
+#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
--- /dev/null
+/*
+ * 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
--- /dev/null
+#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
--- /dev/null
+/*
+ * 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;
+}
+
+}
+
+}
+
+}
--- /dev/null
+#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
--- /dev/null
+#version 430
+
+layout( location = 0 ) in vec4 triColor;
+layout( location = 0 ) out vec4 outColor;
+
+void main()
+{
+ outColor = triColor;
+}
\ No newline at end of file
--- /dev/null
+#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
-//
-// 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
-//
-// 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>
{
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;
};
+
}
}
}
*/
// 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
{
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 */
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
{
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{},
/** 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,
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
*/
// 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
{
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
-#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.
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
--- /dev/null
+/*
+ * 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
--- /dev/null
+#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
+++ /dev/null
-#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
+++ /dev/null
-//
-// 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
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
-#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.
{
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
--- /dev/null
+/*
+ * 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
--- /dev/null
+#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
/*
- * 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
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())
}
}
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wframe-larger-than="
+
void Graphics::PreparePhysicalDevice()
{
auto devices = VkAssert(mInstance.enumeratePhysicalDevices());
GetQueueFamilyProperties();
- mDeviceMemoryManager = MakeUnique<DeviceMemoryManager>( *this );
+ mDeviceMemoryManager = GpuMemoryManager::New( *this );
}
#pragma GCC diagnostic pop
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
-#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.
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
{
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;
const vk::AllocationCallbacks& GetAllocator() const;
- DeviceMemoryManager& GetDeviceMemoryManager() const
+ GpuMemoryManager& GetDeviceMemoryManager() const
{
return *mDeviceMemoryManager;
}
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};
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
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()));
-#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.
EXTERNAL
};
-class Image : public Resource
+class Image : public VkManaged
{
public:
/**
* @param info
* @return
*/
- UniqueImageView CreateView(const vk::ImageViewCreateInfo& info);
+ ImageViewRef CreateView(const vk::ImageViewCreateInfo& info);
/**
* Returns underlying Vulkan object
* ImageView
* todo: move it to its own file
*/
-class ImageView : public Resource
+class ImageView : public VkManaged
{
public:
ImageView(Graphics& graphics, Image& image);
Image& GetImage() const
{
- return mImageRef.GetResource();
+ return *mImageRef;
}
private:
+
Graphics& mGraphics;
- ResourceRef<Image> mImageRef;
+ Handle<Image> mImageRef;
vk::ImageView mImageView;
};
} // namespace Dali
-#endif // DALI_GRAPHICS_VULKAN_IMAGE_H
+#endif // DALI_GRAPHICS_VULKAN_IMAGE
--- /dev/null
+/*
+ * 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
--- /dev/null
+#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
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);
}
// 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
{
}
-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);
#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);
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);
}
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;
}
-#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.
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
/** 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;
};
} // namespace Vulkan
+
} // namespace Graphics
+
} // namespace Dali
-#endif // DALI_GRAPHICS_VULKAN_QUEUE_H
+#endif // DALI_GRAPHICS_VULKAN_QUEUE
--- /dev/null
+/*
+ * 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
--- /dev/null
+#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
#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)
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()
{
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();
+}
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
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();
* 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{};
.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();
// submit
auto& queue = mGraphics.GetGraphicsQueue();
- queue.Submit(*swapImage.mainCmdBuf.get(), *mFrameFence.get())->WaitForFence();
+ queue.Submit(swapImage.mainCmdBuf, mFrameFence)->WaitForFence();
}
void Surface::Present()
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);
{
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
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
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();
}
-#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.
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
*/
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);
vk::ImageView mDepthStencilImageView;
vk::DeviceMemory mDepthStencilMemory;
- UniqueCommandPool mCommandPool;
+ Handle<CommandPool> mCommandPool;
vk::Format mFormat;
vk::ColorSpaceKHR mColorSpace;
std::vector< SwapchainImage > mSwapImages;
std::unique_ptr< vk::SurfaceCapabilitiesKHR > mCapabilities;
- UniqueFence mFrameFence;
+ Handle<Fence> mFrameFence;
vk::RenderPass mDefaultRenderPass;
uint32_t mBufferCount;
} // namespace Graphics
} // namespace Dali
-#endif // DALI_GRAPHICS_VULKAN_SURFACE_H
+#endif // DALI_GRAPHICS_VULKAN_SURFACE
-#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.
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
* 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)
{
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;
}
/*
+ * 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
} // namespace Graphics
} // namespace Dali
-#endif // DALI_GRAPHICS_VULKAN_TYPES_H
+#endif // DALI_GRAPHICS_VULKAN_TYPES
// create device
mGraphicsImpl->CreateDevice();
+ // create swapchain
+ mGraphicsImpl->GetSurface( retval ).CreateSwapchain();
+
return retval;
}
*/
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
*/