Designed for better integration with Dali adaptor.
- Image, Buffer and DeviceMemory brought back.
- Added ImageView
- Added Resource user counting
Change-Id: I7d35e8584f50d844ba76c25f37004daf0ef91304
$(dali_core_includes) \
$(DALI_CFLAGS)
+
+DALI_CORE_LA_LDFLAGS = $(DALI_LDFLAGS) -Wl,--whole-archive,graphics/libdali-graphics.a,--no-whole-archive
+
DALI_CORE_LA_LIBADD = $(DALI_LDFLAGS) \
- graphics/libdali-graphics.a \
+ $(VULKAN_LIBS) \
-lpthread
dali_core_includes = \
# Install headers under the correct subdirectories
platformabstractiondir = $(includedir)/dali/integration-api
platformabstractioneventsdir = $(includedir)/dali/integration-api/events
+platformabstractiongraphicsdir = $(includedir)/dali/integration-api/graphics
platformabstraction_HEADERS = $(platform_abstraction_header_files)
platformabstractionevents_HEADERS = $(platform_abstraction_events_header_files)
+platformabstractiongraphics_HEADERS = $(graphics_integration_header_files)
#devel api (used by adaptor / toolkit
develapidir = $(devincludepath)/dali/devel-api
# linking test
-noinst_PROGRAMS = linker.test
-
-linker_test_SOURCES = linker-test.cpp \
- ../../../automated-tests/src/dali/dali-test-suite-utils/test-application.cpp \
- ../../../automated-tests/src/dali/dali-test-suite-utils/test-platform-abstraction.cpp \
- ../../../automated-tests/src/dali/dali-test-suite-utils/test-render-controller.cpp \
- ../../../automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.cpp \
- ../../../automated-tests/src/dali/dali-test-suite-utils/test-gesture-manager.cpp \
- ../../../automated-tests/src/dali/dali-test-suite-utils/test-gl-sync-abstraction.cpp \
- ../../../automated-tests/src/dali/dali-test-suite-utils/test-trace-call-stack.cpp
-
-linker_test_CXXFLAGS = \
- $(cxx_flags) \
- -I../../../automated-tests/src/dali/dali-test-suite-utils \
- $(dali_core_includes)
-
-if ENABLE_CXX03_ABI
-
-linker_test_DEPENDENCIES = libdali-core.la
-linker_test_LDADD = \
- libdali-core.la
-
-if ENABLE_RENAME_SO
+#noinst_PROGRAMS = linker.test
+#
+#linker_test_SOURCES = linker-test.cpp \
+# ../../../automated-tests/src/dali/dali-test-suite-utils/test-application.cpp \
+# ../../../automated-tests/src/dali/dali-test-suite-utils/test-platform-abstraction.cpp \
+# ../../../automated-tests/src/dali/dali-test-suite-utils/test-render-controller.cpp \
+# ../../../automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.cpp \
+# ../../../automated-tests/src/dali/dali-test-suite-utils/test-gesture-manager.cpp \
+# ../../../automated-tests/src/dali/dali-test-suite-utils/test-gl-sync-abstraction.cpp \
+# ../../../automated-tests/src/dali/dali-test-suite-utils/test-trace-call-stack.cpp
+#
+#linker_test_CXXFLAGS = \
+# $(cxx_flags) \
+# -I../../../automated-tests/src/dali/dali-test-suite-utils \
+# $(dali_core_includes)
+#
+#if ENABLE_CXX03_ABI
+#
+#linker_test_DEPENDENCIES = libdali-core.la
+#linker_test_LDADD = \
+# libdali-core.la
+#
+#if ENABLE_RENAME_SO
#rename
-install: install-am
- rm -rf $(libdir)/libdali-core.so
- rm -rf $(libdir)/libdali-core-cxx03.so
- ln -s $(libdir)/libdali-core.so.0.0.* $(libdir)/libdali-core-cxx03.so
-endif
-
-else
-
-linker_test_DEPENDENCIES = libdali-core-cxx11.la
-linker_test_LDADD = \
- libdali-core-cxx11.la
-
-if ENABLE_RENAME_SO
+#install: install-am
+# rm -rf $(libdir)/libdali-core.so
+# rm -rf $(libdir)/libdali-core-cxx03.so
+# ln -s $(libdir)/libdali-core.so.0.0.* $(libdir)/libdali-core-cxx03.so
+#endif
+#
+#else
+#
+#linker_test_DEPENDENCIES = libdali-core-cxx11.la
+#linker_test_LDADD = \
+# libdali-core-cxx11.la
+#
+#if ENABLE_RENAME_SO
#rename
-install: install-am
- rm -rf $(libdir)/libdali-core-cxx11.so
- rm -rf $(libdir)/libdali-core.so
- ln -s $(libdir)/libdali-core-cxx11.so.0.0.* $(libdir)/libdali-core.so
-endif
-
-endif
+#install: install-am
+# rm -rf $(libdir)/libdali-core-cxx11.so
+# rm -rf $(libdir)/libdali-core.so
+# ln -s $(libdir)/libdali-core-cxx11.so.0.0.* $(libdir)/libdali-core.so
+#endif
+#
+#endif
-# Copyright (c) 2016 Samsung Electronics Co., Ltd.
+# 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.
graphics_src_dir = ../../../../dali/graphics
include ../../../../dali/graphics/file.list
+graphics_integration_dir = ../../../../dali/integration-api/graphics
+include ../../../../dali/integration-api/graphics/file.list
# Build the graphics library
noinst_LIBRARIES = libdali-graphics.a
libdali_graphics_a_SOURCES = $(graphics_api_src_files) \
- $(graphics_src_files)
+ $(graphics_src_files) \
+ $(graphics_integration_src_files)
#libdali_graphics_a_LDFLAGS = -fPIC
graphics_src_files = \
$(graphics_src_dir)/graphics-controller.cpp \
- $(graphics_src_dir)/graphics-controller.cpp \
- $(graphics_src_dir)/graphics-logical-device.cpp \
- $(graphics_src_dir)/graphics-physical-device.cpp \
- $(graphics_src_dir)/graphics-surface.cpp \
- $(graphics_src_dir)/graphics-swapchain.cpp \
- $(graphics_src_dir)/vulkan/image.cpp \
- $(graphics_src_dir)/vulkan/device-memory.cpp \
- $(graphics_src_dir)/vulkan/command-queue.cpp \
- $(graphics_src_dir)/vulkan/surface.cpp \
- $(graphics_src_dir)/vulkan/logical-device.cpp \
- $(graphics_src_dir)/vulkan/command-buffer.cpp \
- $(graphics_src_dir)/vulkan/image-view.cpp \
- $(graphics_src_dir)/vulkan/command-pool.cpp \
- $(graphics_src_dir)/vulkan/framebuffer.cpp \
- $(graphics_src_dir)/vulkan/physical-device.cpp \
- $(graphics_src_dir)/vulkan/swapchain.cpp \
- $(graphics_src_dir)/vulkan/buffer.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
+
+++ /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/graphics-logical-device.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-
-GraphicsSwapchain GraphicsLogicalDevice::CreateSwapchain(const GraphicsSurface& surface,
- uint32_t bufferCount,
- DepthStencil depthStencil,
- VSyncMode enforceVSync)
-{
- return GetObject()->CreateSwapchain(surface, bufferCount, depthStencil, enforceVSync);
-}
-}
-}
+++ /dev/null
-#ifndef DALI_CORE_GRAPHICS_GRAPHICS_LOGICAL_DEVICE_H
-#define DALI_CORE_GRAPHICS_GRAPHICS_LOGICAL_DEVICE_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/graphics-swapchain.h>
-#include <dali/graphics/integration/graphics-logical-device-base.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-
-using GraphicsLogicalDeviceHandle = VkHandleBase< GraphicsLogicalDeviceBase >;
-
-class GraphicsLogicalDevice : public GraphicsLogicalDeviceHandle
-{
-public:
- GraphicsLogicalDevice(GraphicsLogicalDeviceBase* impl = nullptr)
- : GraphicsLogicalDeviceHandle{impl}
- {
- }
-
- using GraphicsLogicalDeviceHandle::operator=;
-
- GraphicsSwapchain CreateSwapchain(const GraphicsSurface& surface,
- uint32_t bufferCount,
- DepthStencil depthStencil,
- VSyncMode enforceVSync);
-};
-
-} // Graphics
-} // Dali
-
-#endif //DALI_CORE_GRAPHICS_GRAPHICS_LOGICAL_DEVICE_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/graphics-physical-device.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-
-GraphicsPhysicalDevice GraphicsPhysicalDevice::New()
-{
- return GraphicsPhysicalDevice(nullptr);
-}
-
-bool GraphicsPhysicalDevice::Initialise(const ExtensionNameList& extensions, const ValidationLayerFlags2& layers)
-{
- return GetObject()->Initialise(extensions, layers);
-}
-
-bool GraphicsPhysicalDevice::IsExtensionAvailable(const std::string& instanceExtensionName) const
-{
- return GetObject()->IsExtensionAvailable(instanceExtensionName);
-}
-
-bool GraphicsPhysicalDevice::IsLayerAvailable(const std::string& instanceLayerName) const
-{
- return GetObject()->IsLayerAvailable(instanceLayerName);
-}
-
-bool GraphicsPhysicalDevice::ChoosePhysicalDevice(const PhysicalDeviceFlags& flags)
-{
- return GetObject()->ChoosePhysicalDevice(flags);
-}
-
-GraphicsLogicalDevice GraphicsPhysicalDevice::CreateLogicalDevice(const ExtensionNameList& enabledExtensions)
-{
- return GetObject()->CreateLogicalDevice(enabledExtensions);
-}
-
-GraphicsLogicalDevice GraphicsPhysicalDevice::CreateLogicalDevice()
-{
- return CreateLogicalDevice(ExtensionNameList());
-}
-
-GraphicsSurface GraphicsPhysicalDevice::CreateSurface(const NativeSurfaceCreateInfo& info)
-{
- return GetObject()->CreateSurface(info);
-}
-
-} // Graphics
-} // Dali
\ No newline at end of file
+++ /dev/null
-#ifndef DALI_CORE_GRAPHICS_PHYSICAL_DEVICE_H
-#define DALI_CORE_GRAPHICS_PHYSICAL_DEVICE_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/graphics-logical-device.h>
-#include <dali/graphics/graphics-surface.h>
-#include <dali/graphics/integration/graphics-physical-device-base.h>
-#include <dali/graphics/vulkan/common.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-
-class GraphicsPhysicalDevice : public VkHandleBase< Integration::GraphicsPhysicalDeviceBase >
-{
-public:
- GraphicsPhysicalDevice(Integration::GraphicsPhysicalDeviceBase* impl = nullptr)
- : VkHandleBase{impl}
- {
- }
-
- using VkHandleBase::operator=;
-
-public:
- /**
- * Creates new uninitialised physical device
- * @return
- */
- static GraphicsPhysicalDevice New();
-
- /**
- *
- * @param extensions
- * @param layers
- * @return
- */
- bool Initialise(const ExtensionNameList& extensions, const ValidationLayerFlags2& layers);
-
- /**
- *
- * @param instanceExtensionName
- * @return
- */
- bool IsExtensionAvailable(const std::string& instanceExtensionName) const;
-
- /**
- *
- * @param instanceExtensionName
- * @return
- */
- bool IsLayerAvailable(const std::string& instanceExtensionName) const;
-
- /**
- *
- * @param flags
- * @return
- */
- bool ChoosePhysicalDevice(const PhysicalDeviceFlags& flags = 0u);
-
- /**
- * Creates logical device from the physical device
- * @param enabledExtensions
- * @return
- */
- GraphicsLogicalDevice CreateLogicalDevice(const ExtensionNameList& enabledExtensions);
-
- /**
- *
- * @return
- */
- GraphicsLogicalDevice CreateLogicalDevice();
-
- // temporary solution to bind physical device with surface
- /**
- *
- * @param info
- * @return
- */
- GraphicsSurface CreateSurface(const NativeSurfaceCreateInfo& info);
-};
-
-using PhysicalDeviceHandle = VkHandleBase< Integration::GraphicsPhysicalDeviceBase >;
-
-} // Graphics
-} // Dali
-
-#endif //DALI_CORE_GRAPHICSPHYSICALDEVICE_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/graphics-surface.h>
-#include <dali/graphics/integration/graphics-surface-base.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-bool GraphicsSurface::Initialise()
-{
- return GetObject()->Initialise();
-}
-
-bool GraphicsSurface::Replace()
-{
- return GetObject()->Replace();
-}
-
-bool GraphicsSurface::Destroy()
-{
- return GetObject()->Destroy();
-}
-
-uint32_t GraphicsSurface::GetWidth()
-{
- return GetObject()->GetWidth();
-}
-
-uint32_t GraphicsSurface::GetHeight()
-{
- return GetObject()->GetHeight();
-}
-
-}
-}
\ No newline at end of file
+++ /dev/null
-#ifndef DALI_CORE_GRAPHICS_SURFACE_H
-#define DALI_CORE_GRAPHICS_SURFACE_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/integration/graphics-surface-base.h>
-#include <dali/graphics/vulkan/common.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-class GraphicsPhysicalDevice;
-
-enum class NativeSurfaceType
-{
- UNDEFINED,
- X11,
- XCB,
- WAYLAND,
- ANDROID_NATIVE_WINDOW,
- WIN32
-};
-
-struct NativeSurfaceCreateInfo
-{
- NativeSurfaceCreateInfo(NativeSurfaceType type) : surfaceType{type}
- {
- }
- NativeSurfaceType surfaceType;
-};
-
-using SurfaceHandle = VkHandleBase< Integration::GraphicsSurfaceBase >;
-
-class GraphicsSurface : public SurfaceHandle
-{
-public:
- GraphicsSurface(Integration::GraphicsSurfaceBase* impl = nullptr) : SurfaceHandle{impl}
- {
- }
- using SurfaceHandle::operator=;
-
- template< typename T, typename... ARGS >
- static GraphicsSurface New(const GraphicsPhysicalDevice& physicalDevice, ARGS&&... args)
- {
- GraphicsSurface retval = (new T(physicalDevice, args...));
- if(!retval.Initialise())
- {
- retval = nullptr;
- }
- return retval;
- }
-
- bool Initialise();
- bool Replace();
- bool Destroy();
- uint32_t GetWidth();
- uint32_t GetHeight();
-
-private:
-};
-}
-}
-
-#endif //DALI_CORE_GRRAPHICSSURFACE_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 "graphics-swapchain.h"
-
-#include <dali/graphics/integration/graphics-swapchain-base.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-
-namespace
-{
-Integration::GraphicsSwapchainBase* GetImpl(SwapchainHandle* handle)
-{
- return handle->GetObject();
-}
-}
-
-void GraphicsSwapchain::Initialise()
-{
- GetImpl(this)->Initialise();
-}
-
-/**
- * Acquires next renderable frame from swapchain
- */
-void GraphicsSwapchain::AcquireFrame()
-{
- GetImpl(this)->AcquireFrame();
-}
-
-/**
- * Presents frame
- */
-void GraphicsSwapchain::PresentFrame()
-{
- GetImpl(this)->PresentFrame();
-}
-}
-}
\ No newline at end of file
+++ /dev/null
-#ifndef DALI_CORE_GRAPHICS_SWAPCHAIN_H
-#define DALI_CORE_GRAPHICS_SWAPCHAIN_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/integration/graphics-swapchain-base.h>
-#include <dali/graphics/vulkan/common.h>
-
-#include <cinttypes>
-
-namespace Dali
-{
-namespace Graphics
-{
-class GraphicsPhysicalDevice;
-
-/**
- * DepthStencil enum values
- */
-enum class DepthStencil
-{
- NONE,
- DEPTH_16,
- DEPTH_24,
- DEPTH_16_STENCIL_8,
- DEPTH_24_STENCIL_8
-};
-
-/**
- * Vsync mode values
- */
-enum class VSyncMode
-{
- DISABLED = 0,
- ENABLED = 1
-};
-
-class GraphicsContext;
-
-using SwapchainHandle = VkHandleBase< Integration::GraphicsSwapchainBase >;
-
-class GraphicsSwapchain : public SwapchainHandle
-{
-public:
-
- GraphicsSwapchain(Integration::GraphicsSwapchainBase* o = nullptr) : SwapchainHandle{o} {};
-
- using SwapchainHandle::operator=;
-
- /**
- * Initialises GraphicsSwapchain
- */
- void Initialise();
-
- /**
- * Acquires next renderable frame from swapchain
- */
- void AcquireFrame();
-
- /**
- * Presents current frame
- */
- void PresentFrame();
-};
-}
-}
-
-#endif //DALI_CORE_GRAPHICSSWAPCHAIN_H
+++ /dev/null
-#ifndef DALI_CORE_GRAPHICS_GRAPHICS_LOGICAL_DEVICE_BASE_H
-#define DALI_CORE_GRAPHICS_GRAPHICS_LOGICAL_DEVICE_BASE_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/graphics-swapchain.h>
-#include <dali/graphics/vulkan/common.h>
-#include <cinttypes>
-
-namespace Dali
-{
-namespace Graphics
-{
-class GraphicsPhysicalDevice;
-class GraphicsSurface;
-
-// base class for context implementation
-class GraphicsLogicalDeviceBase : public VkObject
-{
-public:
- virtual bool Initialise() = 0;
-
- virtual GraphicsSwapchain CreateSwapchain(const GraphicsSurface& surface,
- uint32_t bufferCount,
- DepthStencil depthStencil,
- VSyncMode enforceVSync) = 0;
-
- virtual GraphicsPhysicalDevice GetGraphicsPhysicalDevice() const = 0;
-};
-
-} // Graphics
-} // Dali
-
-#endif //DALI_CORE_GRAPHICS_GRAPHICS_LOGICAL_DEVICE_BASE_H
+++ /dev/null
-#ifndef DALI_CORE_GRAPHICS_PHYSCIAL_DEVICE_BASE_H
-#define DALI_CORE_GRAPHICS_PHYSCIAL_DEVICE_BASE_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/graphics-logical-device.h>
-#include <dali/graphics/graphics-surface.h>
-#include <dali/graphics/vulkan/common.h>
-namespace Dali
-{
-namespace Graphics
-{
-namespace Integration
-{
-
-// abstract class for building the graphics adaptor
-class GraphicsPhysicalDeviceBase : public VkObject
-{
-public:
- /**
- *
- * @param extensions
- * @param layers
- * @return
- */
- virtual bool Initialise(const ExtensionNameList& extensions, const ValidationLayerFlags2& layers) = 0;
-
- /**
- *
- * @param instanceExtensionName
- * @return
- */
- virtual bool IsExtensionAvailable(const std::string& instanceExtensionName) = 0;
-
- /**
- *
- * @param instanceExtensionName
- * @return
- */
- virtual bool IsLayerAvailable(const std::string& instanceExtensionName) = 0;
-
- /**
- *
- * @param surface
- * @return
- */
- virtual GraphicsLogicalDevice CreateLogicalDevice(const ExtensionNameList& enabledExtensions) = 0;
-
- /**
- *
- * @param flags
- * @return
- */
- virtual bool ChoosePhysicalDevice(const PhysicalDeviceFlags& flags) = 0;
-
- /**
- *
- * @param flags
- */
- virtual void SetValidationDebugChannels(const ValidationChannelFlags& flags) = 0;
-
- /**
- *
- * @param info
- * @return
- */
- virtual GraphicsSurface CreateSurface(const NativeSurfaceCreateInfo& info) = 0;
-};
-} // Integration
-} // Graphics
-} // Dali
-
-#endif //DALI_CORE_GRAPHICS_PHYSCIAL_DEVICE_BASE_H
+++ /dev/null
-#ifndef DALI_CORE_GRAPHICS_SURFACE_BASE_H
-#define DALI_CORE_GRAPHICS_SURFACE_BASE_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/common.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-class GraphicsPhysicalDevice;
-
-namespace Vulkan
-{
-
-namespace Internal
-{
-class GraphicsSurfaceBase : public VkObject
-{
-private:
- GraphicsSurfaceBase() = default;
-
-public:
- //GraphicsSurfaceBase(const GraphicsPhysicalDevice &adaptor)
- //{};
- GraphicsSurfaceBase(const GraphicsPhysicalDevice &physicalDevice){};
- virtual ~GraphicsSurfaceBase() = default;
-
- virtual bool Initialise() = 0;
-
- virtual bool Replace() = 0;
-
- virtual bool Destroy() = 0;
-
- virtual uint32_t GetWidth() = 0;
-
- virtual uint32_t GetHeight() = 0;
-};
-}
-
-} // Vulkan
-
-// todo: remove 'internal' namespace
-namespace Integration
-{
-using GraphicsSurfaceBase = Vulkan::Internal::GraphicsSurfaceBase;
-} // Integration
-} // Graphics
-} // Dali
-
-#endif // DALI_CORE_GRAPHICS_SURFACE_BASE_H
+++ /dev/null
-#ifndef DALI_CORE_GRAPHICS_SWAPCHAIN_BASE_H
-#define DALI_CORE_GRAPHICS_SWAPCHAIN_BASE_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/common.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-namespace Integration
-{
-
-class GraphicsSwapchainBase : public VkObject
-{
-public:
- GraphicsSwapchainBase() = default;
- virtual ~GraphicsSwapchainBase() = default;
-
- /**
- * Initialises swapchain
- * @return
- */
- virtual bool Initialise() = 0;
-
- /**
- * Called for new frame to acquire new frame buffer
- * @return
- */
- virtual bool AcquireFrame() = 0;
-
- /**
- * Called at the end of frame to present current frame buffer
- * @return
- */
- virtual bool PresentFrame() = 0;
-
-};
-
-} // Integration
-} // Graphics
-} // Dali
-
-
-#endif // DALI_CORE_GRAPHICS_SWAPCHAIN_BASE_H
+++ /dev/null
-//
-// Created by adam.b on 23/03/17.
-//
-
-#include <vulkan/vulkan.hpp>
-#ifdef __linux__
-#include <X11/Xlib.h>
-#include <unistd.h>
-#endif
-
-
-#include <dali/graphics/graphics-physical-device.h>
-#include <dali/graphics/vulkan/physical-device.h>
-#include <dali/graphics/vulkan/surface/xcb-surface.h>
-#include <dali/graphics/vulkan/surface/xlib-surface.h>
-
-// vulkan specific
-#include <dali/graphics/vulkan/command-queue.h>
-#include <dali/graphics/vulkan/device-memory.h>
-#include <dali/graphics/vulkan/image.h>
-#include <dali/graphics/vulkan/logical-device.h>
-#include <dali/graphics/vulkan/swapchain.h>
-
-using namespace Dali::Graphics;
-
-namespace
-{
-Vulkan::CommandPool gSecondaryCommandPool{nullptr};
-Vulkan::Image gImage{nullptr};
-}
-
-struct TestWindow
-{
- int width, height;
- Display* display;
- ::Window window;
- int defaultScreen;
-} gWnd;
-
-void InitWindow(int width, int height)
-{
- // 1. Create Window ( done by DALI
- gWnd.width = width;
- gWnd.height = height;
- gWnd.display = XOpenDisplay(nullptr);
- gWnd.defaultScreen = DefaultScreen(gWnd.display);
- gWnd.window = XCreateSimpleWindow(gWnd.display, RootWindow(gWnd.display, gWnd.defaultScreen), 0, 0,
- gWnd.width, gWnd.height, 1, BlackPixel(gWnd.display, gWnd.defaultScreen),
- WhitePixel(gWnd.display, gWnd.defaultScreen));
-
- XSelectInput(gWnd.display, gWnd.window, ExposureMask | KeyPressMask);
- XMapWindow(gWnd.display, gWnd.window);
-}
-
-struct XcbWindow
-{
- xcb_connection_t* xcb_connection;
- xcb_screen_t* xcb_screen;
- xcb_window_t xcb_window;
- int width, height;
-} gXcb;
-
-void initXcbWindow(int width, int height)
-{
- // 1. Create Window ( done by DALi )
- gXcb.width = width;
- gXcb.height = height;
- int screenNum(0);
- xcb_connection_t* connection = xcb_connect(NULL, &screenNum);
- const xcb_setup_t* setup = xcb_get_setup(connection);
- xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup);
- for(int i = 0; i < screenNum; ++i)
- xcb_screen_next(&iter);
-
- xcb_screen_t* screen = iter.data;
- xcb_window_t window = xcb_generate_id(connection);
-
- uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
- uint32_t values[] = {screen->white_pixel, XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS};
-
- xcb_create_window(connection, XCB_COPY_FROM_PARENT, window, screen->root, 0, 0, gXcb.width,
- gXcb.height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, mask, values);
-
- xcb_map_window(connection, window);
- const uint32_t coords[] = {100, 100};
- xcb_configure_window(connection, window, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, coords);
- xcb_flush(connection);
-
- gXcb.xcb_connection = connection;
- gXcb.xcb_window = window;
- gXcb.xcb_screen = screen;
-}
-
-void createTexture(const Vulkan::LogicalDevice& device, const Vulkan::CommandBuffer& commandBuffer)
-{
- // create buffer
- const int TEXTURE_SIZE = 1024 * 1024 * 4;
-
- vk::BufferCreateInfo bufInfo;
- bufInfo.setUsage(vk::BufferUsageFlagBits::eTransferSrc)
- .setSharingMode(vk::SharingMode::eExclusive)
- .setQueueFamilyIndexCount(0)
- .setPQueueFamilyIndices(nullptr)
- .setSize(TEXTURE_SIZE);
-
- auto textureBuffer = Vulkan::Buffer::New(device, bufInfo);
- auto memory = device.AllocateBufferMemory(textureBuffer, vk::MemoryPropertyFlagBits::eHostVisible, true);
- void* ptr = memory.Map(0, VK_WHOLE_SIZE);
-
- // Load texture directly into the buffer
- FILE* f = fopen("/tmp/out.rgba", "rb");
- fseek(f, 0, SEEK_END);
- assert(ftell(f) == bufInfo.size);
- fseek(f, 0, SEEK_SET);
- fread(ptr, 1, bufInfo.size, f);
- fclose(f);
-
- // unmap and flush memory
- memory.Unmap();
- memory.Flush();
-
- // create 2D texture image
- vk::ImageCreateInfo imageInfo;
- imageInfo.setSharingMode(vk::SharingMode::eExclusive);
- imageInfo.setUsage(vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferSrc | vk::ImageUsageFlagBits::eTransferDst);
- imageInfo.setInitialLayout(vk::ImageLayout::eUndefined);
- imageInfo.setSamples(vk::SampleCountFlagBits::e1);
- imageInfo.setExtent(vk::Extent3D{1024, 1024, 1});
- imageInfo.setFormat(vk::Format::eR8G8B8A8Unorm);
- imageInfo.setTiling(vk::ImageTiling::eOptimal);
- imageInfo.setMipLevels(1);
- imageInfo.setArrayLayers(1);
- imageInfo.setImageType(vk::ImageType::e2D);
-
- // create vulkan image
- auto image = Vulkan::Image::New(device, imageInfo);
- auto imageMemory = device.AllocateImageMemory(image, vk::MemoryPropertyFlagBits::eDeviceLocal, true);
-
- if(!gSecondaryCommandPool)
- {
- gSecondaryCommandPool = device.CreateCommandPool(QueueType::TRANSFER, true, true);
- }
-
- // record
- Vulkan::CommandBuffer cmdBuf = gSecondaryCommandPool.AllocateCommandBuffer(true);
- vk::BufferImageCopy region;
- region.setImageExtent({1024, 1024, 1});
- region.setImageSubresource(vk::ImageSubresourceLayers()
- .setAspectMask(vk::ImageAspectFlagBits::eColor)
- .setMipLevel(0)
- .setLayerCount(1)
- .setBaseArrayLayer(0));
-
- auto layoutBarrier =
- image.GetLayoutChangeBarrier(vk::ImageLayout::eTransferDstOptimal, vk::AccessFlags(),
- vk::AccessFlagBits::eTransferWrite, vk::ImageAspectFlagBits::eColor);
-
- cmdBuf.Begin(true);
- cmdBuf->pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTopOfPipe,
- vk::DependencyFlags(), 0, nullptr, 0, nullptr, 1, &layoutBarrier);
- cmdBuf->copyBufferToImage(*textureBuffer, *image, vk::ImageLayout::eTransferDstOptimal, 1, ®ion);
-
- image.SetLayout( vk::ImageLayout::eTransferDstOptimal );
- auto layoutBarrier2 =
- image.GetLayoutChangeBarrier(vk::ImageLayout::eTransferSrcOptimal, vk::AccessFlags(),
- vk::AccessFlagBits::eTransferWrite, vk::ImageAspectFlagBits::eColor);
-
-
- cmdBuf->pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe, vk::PipelineStageFlagBits::eTopOfPipe,
- vk::DependencyFlags(), 0, nullptr, 0, nullptr, 1, &layoutBarrier2);
-
- image.SetLayout( vk::ImageLayout::eTransferSrcOptimal );
- cmdBuf.End();
-
- auto queue = device.GetCommandQueue(0, QueueType::TRANSFER);
- queue.Submit(&cmdBuf, 1, nullptr);
-
- // should use fence
- queue.WaitIdle();
-
- gImage = image;
- return;
-}
-
-int main(int argc, char** argv)
-{
-
- InitWindow(720, 360);
- // make physical device from vulkan device ( should be done through some sort of
- // implementation factory )
- GraphicsPhysicalDevice physDevice(Vulkan::PhysicalDevice::New());
- ExtensionNameList list;
-
- // check extensions ( vulkan specific )
-
- NativeSurfaceType surfaceType = NativeSurfaceType::UNDEFINED;
-
- if(physDevice.IsExtensionAvailable(VK_KHR_SURFACE_EXTENSION_NAME))
- list.emplace_back(VK_KHR_SURFACE_EXTENSION_NAME);
- if(physDevice.IsExtensionAvailable(VK_KHR_XCB_SURFACE_EXTENSION_NAME))
- {
- list.emplace_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
- //surfaceType = NativeSurfaceType::XCB;
- }
- if(physDevice.IsExtensionAvailable(VK_KHR_XLIB_SURFACE_EXTENSION_NAME))
- {
- list.emplace_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
- if(surfaceType == NativeSurfaceType::UNDEFINED)
- surfaceType = NativeSurfaceType::X11;
- }
-
- physDevice.Initialise(list,
- ValidationLayerFlags2() | ValidationLayerBit2::CORE_VALIDATION |
- ValidationLayerBit2::STANDARD_VALIDATION |
- ValidationLayerBit2::PARAMETER_VALIDATION | ValidationLayerBit2::API_DUMP);
-
- // reporting on all channels
- //physDevice.SetValidationDebugChannels(ValidationChannelBit::ALL);
-
- bool result = physDevice.ChoosePhysicalDevice(PhysicalDeviceBit::ANY);
-
- GraphicsSurface surface{nullptr};
-
- if(surfaceType == NativeSurfaceType::XCB)
- {
- XcbSurfaceCreateInfo info;
- info.connection = gXcb.xcb_connection;
- info.window = gXcb.xcb_window;
- surface = physDevice.CreateSurface(info);
- }
- else
- {
- XlibSurfaceCreateInfo info;
- info.display = gWnd.display;
- info.window = gWnd.window;
- surface = physDevice.CreateSurface(info);
- }
- auto logicalDevice = physDevice.CreateLogicalDevice();
-
- auto swapchain = logicalDevice.CreateSwapchain(surface, 2, DepthStencil::NONE, VSyncMode::DISABLED);
-
- // obtain vulkan interface
- auto vkSwapchain = swapchain.Cast< Vulkan::Swapchain >();
- auto vkDevice = logicalDevice.Cast< Vulkan::LogicalDevice >();
-
- createTexture(vkDevice, vkSwapchain.GetCurrentCommandBuffer());
-
- bool running = true;
-
- while(running)
- {
- swapchain.AcquireFrame();
- auto cmdbuf = vkSwapchain.GetCurrentCommandBuffer();
- vk::ImageCopy region;
-
- vk::ImageSubresourceLayers subres;
- subres.setBaseArrayLayer(0).setAspectMask(vk::ImageAspectFlagBits::eColor).setLayerCount(1).setMipLevel(0);
-
- region.setExtent({100, 100, 1})
- .setDstOffset({0, 0, 0})
- .setSrcOffset({0, 0, 0})
- .setSrcSubresource(subres)
- .setDstSubresource(subres);
-
- cmdbuf->copyImage(*gImage, gImage.GetLayout(), vkSwapchain.GetCurrentImage(),
- vk::ImageLayout::eColorAttachmentOptimal, 1, ®ion);
- usleep(1000);
- swapchain.PresentFrame();
- }
-
- return 0;
-}
-
-int main_(int argc, char** argv)
-{
- initXcbWindow(720, 360);
-
-#if 0
- // using template argument to pick adaptor implementation
- GraphicsPhysicalDevice adaptor = GraphicsPhysicalDevice::GraphicsPhysicalDevice< Internal::VulkanAdaptor >();
- ExtensionNameList list;
-
- // check extension
- if(adaptor.IsExtensionAvailable(VK_KHR_SURFACE_EXTENSION_NAME))
- list.emplace_back(VK_KHR_SURFACE_EXTENSION_NAME);
- if(adaptor.IsExtensionAvailable(VK_KHR_XLIB_SURFACE_EXTENSION_NAME))
- list.emplace_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
- if(adaptor.IsExtensionAvailable(VK_KHR_XCB_SURFACE_EXTENSION_NAME))
- list.emplace_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
-
- // initialise
- adaptor.Initialise(list,
- ValidationLayerFlags()
- | ValidationLayerBit2::CORE_VALIDATION |
- ValidationLayerBit2::STANDARD_VALIDATION |
- ValidationLayerBit2::PARAMETER_VALIDATION | ValidationLayerBit2::API_DUMP);
-
- // reporting on all channels
- adaptor.SetValidationDebugChannels(ValidationChannelBit::ALL);
-
- // choose first available physical adaptor
- bool result = adaptor.ChoosePhysicalDevice(PhysicalDeviceBit::ANY);
-
- if(!result) // no requested device available ( maybe adding enumeration )
- {
- // fixme, something went very wrong
- }
-
- // create surface for X11 ( could be templated GraphicsPhysicalDevice function? )
- auto surface = adaptor.CreateSurface< Internal::GraphicsXcbSurface >(adaptor, gXcb.xcb_connection, gXcb.xcb_window);
-
- if(!surface)
- {
- VkLog("No surface dammit!");
- }
-
- // create context
- auto context = adaptor.CreateContext(surface);
-
- // create swapchain ( 2 buffers )
- auto swapchain = context.CreateSwapchain(surface, 3, DepthStencil::NONE, true);
-
- while( 1 )
- {
- swapchain.AcquireFrame();
- usleep(1000);
- //swapchain.SwapBuffers( true );
- swapchain.PresentFrame();
- }
-
- return 0;
-}
-
-int _main(int argc, char** argv)
-{
-#if 0
- InitWindow(720, 360);
-
- GraphicsPhysicalDevice adaptor;
- ExtensionNameList list;
-
- // check extension
- if(adaptor.IsExtensionAvailable(VK_KHR_SURFACE_EXTENSION_NAME))
- list.emplace_back(VK_KHR_SURFACE_EXTENSION_NAME);
- if(adaptor.IsExtensionAvailable(VK_KHR_XLIB_SURFACE_EXTENSION_NAME))
- list.emplace_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
-
- // initialise
- adaptor.Initialise(list, ValidationLayerFlags() |
- ValidationLayerBit2::CORE_VALIDATION | ValidationLayerBit2::STANDARD_VALIDATION |
- ValidationLayerBit2::PARAMETER_VALIDATION|ValidationLayerBit2::API_DUMP);
-
- // reporting on all channels
- adaptor.SetValidationDebugChannels( ValidationChannelBit::ALL );
-
- // choose first available physical adaptor
- bool result = adaptor.ChoosePhysicalDevice(PhysicalDeviceBit::ANY);
-
- if( !result ) // no requested device available ( maybe adding enumeration )
- {
- // fixme, something went very wrong
- }
-
- // create surface for X11 ( could be templated GraphicsPhysicalDevice function? )
- //auto& surface = GraphicsSurfaceBase::CreateSurface<GraphicsXlibSurface>( adaptor, gWnd.display, gWnd.window );
- auto& surface = adaptor.CreateSurface<GraphicsXlibSurface>( adaptor, gWnd.display, gWnd.window );
-
- if( surface == nullptr )
- {
- // surface invalid :((((
- }
- // create context
- GraphicsContext context = adaptor.CreateContext(surface);
-
- // create swapchain with 2 buffers
- GraphicsSwapchain swapchain = context.CreateSwapchain( surface, 2 );
-
-#endif
-#endif
- return 0;
-}
\ No newline at end of file
+++ /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/buffer.h>
-#include <dali/graphics/vulkan/device-memory.h>
-#include <dali/graphics/vulkan/logical-device.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-namespace Vulkan
-{
-// Implementation
-
-class BufferImpl : public VkObject
-{
-public:
- BufferImpl(const LogicalDevice& device, const vk::BufferCreateInfo& info)
- : mDevice(device), mCreateInfo(info)
- {
- }
-
- virtual ~BufferImpl();
-
- bool Initialise();
-
- const vk::Buffer& GetVkBuffer() const
- {
- return mBuffer;
- }
-
- const DeviceMemory& GetDeviceMemory() const
- {
- return mDeviceMemory;
- }
-
- bool BindDeviceMemory(const DeviceMemory& memory, size_t offset);
-
-private:
- LogicalDevice mDevice{nullptr};
- DeviceMemory mDeviceMemory{nullptr}; // bound device memory
- vk::BufferCreateInfo mCreateInfo{};
- vk::Buffer mBuffer{nullptr};
- size_t mMemoryBoundOffset{0u};
-};
-
-BufferImpl::~BufferImpl()
-{
- if(mBuffer)
- {
- mDevice.GetVkDevice().destroyBuffer(mBuffer, mDevice.GetVkAllocator());
- }
-}
-
-bool BufferImpl::Initialise()
-{
- return VkTestBool(mDevice.GetVkDevice().createBuffer(&mCreateInfo, mDevice.GetVkAllocator(), &mBuffer));
-}
-
-bool BufferImpl::BindDeviceMemory(const DeviceMemory& memory, size_t offset)
-{
- assert(!mDeviceMemory && "There is a DeviceMemory already bound!");
- if(VkTestBool(mDevice->bindBufferMemory(mBuffer, *memory, offset)))
- {
- mDeviceMemory = memory;
- mMemoryBoundOffset = offset;
- return true;
- }
- return false;
-}
-
-// Handle
-namespace
-{
-BufferImpl* GetImpl(Buffer* handle)
-{
- return static_cast< BufferImpl* >(handle->GetObject());
-}
-BufferImpl* GetImpl(const Buffer* handle)
-{
- return static_cast< BufferImpl* >(handle->GetObject());
-}
-}
-
-Buffer Buffer::New(const LogicalDevice& device, const vk::BufferCreateInfo& info)
-{
- auto impl = new BufferImpl(device, info);
- if(impl->Initialise())
- {
- return impl;
- }
- return nullptr;
-}
-
-const vk::Buffer& Buffer::GetVkResource() const
-{
- return GetImpl(this)->GetVkBuffer();
-}
-
-const vk::Buffer& Buffer::operator*() const
-{
- return GetImpl(this)->GetVkBuffer();
-}
-
-bool Buffer::BindDeviceMemory(const DeviceMemory& memory)
-{
- return GetImpl(this)->BindDeviceMemory(memory, 0);
-}
-
-bool Buffer::BindDeviceMemory(const DeviceMemory& memory, size_t offset)
-{
- return GetImpl(this)->BindDeviceMemory(memory, offset);
-}
-}
-}
-}
\ No newline at end of file
+++ /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/command-buffer.h>
-#include <dali/graphics/vulkan/command-pool.h>
-#include <dali/graphics/vulkan/logical-device.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-namespace Vulkan
-{
-using State = CommandBufferState;
-class CommandBufferImpl : public VkObject
-{
-public:
- CommandBufferImpl(const LogicalDevice& context, const CommandPool& pool,
- vk::CommandBufferLevel level, vk::CommandBuffer buffer)
- : VkObject{}, mPool{pool}, mDevice{context}, mBuffer{buffer}, mLevel{level}
- {
- }
-
- bool OnSafeDelete() override
- {
- // mind that the resources may not be released if the pool doesn't allow
- // freeing a single command buffer! Synchronization is explicit
- if(mPool)
- {
- mDevice.GetVkDevice().freeCommandBuffers(mPool.GetCommandPool(), 1, &mBuffer);
- return true;
- }
- else
- {
- return false;
- }
- }
-
- const vk::CommandBuffer& GetVkCommandBuffer() const
- {
- return mBuffer;
- }
-
- const CommandPool& GetCommandPool() const
- {
- return mPool;
- }
-
- State GetState() const
- {
- return mState;
- }
-
- bool Begin(bool oneTimeSubmit, bool renderPassContinue, bool simultaneousUse);
- bool End();
- bool Free();
- bool Reset();
-
-private:
- CommandPool mPool;
- LogicalDevice mDevice;
- vk::CommandBuffer mBuffer;
- vk::CommandBufferLevel mLevel;
-
- // state of command buffer
- State mState{State::UNDEFINED};
-};
-
-bool CommandBufferImpl::Begin(bool oneTimeSubmit, bool renderPassContinue, bool simultaneousUse)
-{
- // check state
- if(mState != State::CREATED && mState != State::UNDEFINED && mState != State::RESET)
- {
- VkLog("[VKCMDBUF] Invalid buffer state: %d", static_cast< int >(mState));
- return false;
- }
-
- vk::CommandBufferUsageFlags flags{};
- if(oneTimeSubmit)
- {
- flags |= vk::CommandBufferUsageFlagBits::eOneTimeSubmit;
- }
- if(renderPassContinue)
- {
- flags |= vk::CommandBufferUsageFlagBits::eRenderPassContinue;
- }
- if(simultaneousUse)
- {
- flags |= vk::CommandBufferUsageFlagBits::eSimultaneousUse;
- }
-
- // todo implement inheritance
- vk::CommandBufferBeginInfo info;
- info.setFlags(flags).setPInheritanceInfo(nullptr);
-
- if(VkTestCall(mBuffer.begin(&info)) == vk::Result::eSuccess)
- {
- mState = State::RECORDING;
- return true;
- }
-
- return false;
-}
-
-bool CommandBufferImpl::End()
-{
- // check state
- if(mState != State::RECORDING)
- {
- VkLog("[VKCMDBUF] Invalid buffer state: %d, it must be RECORDING", static_cast< int >(mState));
- return false;
- }
-
- if(VkTestCall(mBuffer.end()) == vk::Result::eSuccess)
- {
- mState = State::RECORDED;
- return true;
- }
- return false;
-}
-
-bool CommandBufferImpl::Free()
-{
- // todo
- assert(false && "CommandBufferImpl::Free() unimplemented!");
-}
-
-bool CommandBufferImpl::Reset()
-{
- if(vk::Result::eSuccess == VkTestCall(mBuffer.reset(vk::CommandBufferResetFlagBits::eReleaseResources)))
- {
- mState = State::RESET;
- }
- return true;
-}
-
-// Implementation getter
-namespace
-{
-CommandBufferImpl* GetImpl(CommandBuffer* handle)
-{
- return static_cast< CommandBufferImpl* >(handle->GetObject());
-}
-CommandBufferImpl* GetImpl(const CommandBuffer* handle)
-{
- return static_cast< CommandBufferImpl* >(handle->GetObject());
-}
-}
-
-const vk::CommandBuffer* CommandBuffer::operator->() const
-{
- auto& vkcmdbuf = GetImpl(this)->GetVkCommandBuffer();
- return &vkcmdbuf;
-}
-
-std::vector< CommandBuffer > CommandBuffer::New(const CommandPool& pool, bool isPrimary, uint32_t count)
-{
- auto vkDevice = pool.GetLogicalDevice().GetVkDevice();
-
- std::vector< vk::CommandBuffer > buffers(count);
-
- auto bufferLevel = isPrimary ? vk::CommandBufferLevel::ePrimary : vk::CommandBufferLevel::eSecondary;
-
- {
- vk::CommandBufferAllocateInfo info;
- info.setCommandBufferCount(count).setCommandPool(pool.GetCommandPool()).setLevel(bufferLevel);
-
- VkAssertCall(vkDevice.allocateCommandBuffers(&info, buffers.data()));
- }
-
- // move buffers data
- std::vector< CommandBuffer > output(buffers.size());
-
- for(auto&& cmdbuf : buffers)
- {
- output.emplace_back(new CommandBufferImpl(pool.GetLogicalDevice(), pool, bufferLevel, cmdbuf));
- }
- return std::move(output);
-}
-
-CommandBuffer CommandBuffer::New(const CommandPool& pool, bool isPrimary)
-{
- // todo make more efficient implementation
- return CommandBuffer::New(pool, isPrimary, 1)[0];
-}
-
-bool CommandBuffer::Begin(bool oneTimeSubmit, bool renderPassContinue, bool simultaneousUse)
-{
- return GetImpl(this)->Begin(oneTimeSubmit, renderPassContinue, simultaneousUse);
-}
-
-bool CommandBuffer::End()
-{
- return GetImpl(this)->End();
-}
-
-bool CommandBuffer::Free()
-{
- return GetImpl(this)->Free();
-}
-
-bool CommandBuffer::Reset()
-{
- return GetImpl(this)->Reset();
-}
-
-CommandBufferState CommandBuffer::GetState() const
-{
- return GetImpl(this)->GetState();
-}
-
-vk::CommandBuffer CommandBuffer::GetVkBuffer() const
-{
- return GetImpl(this)->GetVkCommandBuffer();
-}
-
-const CommandPool& CommandBuffer::GetCommandPool() const
-{
- return GetImpl(this)->GetCommandPool();
-}
-
-std::thread::id CommandBuffer::GetThreadId() const
-{
- return std::thread::id{};
-}
-}
-}
-}
+++ /dev/null
-#ifndef DALI_CORE_GRAPHICS_VULKAN_COMMAND_BUFFER_H
-#define DALI_CORE_GRAPHICS_VULKAN_COMMAND_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/common.h>
-#include <thread>
-
-namespace Dali
-{
-namespace Graphics
-{
-namespace Vulkan
-{
-
-enum class CommandBufferState
-{
- UNDEFINED,
- CREATED,
- RESET,
- RECORDING,
- RECORDED,
- SUBMITTED
-};
-
-class CommandPool;
-class CommandBuffer : public VkHandle
-{
-public:
- CommandBuffer(VkObject* impl = nullptr) : VkHandle{impl}
- {
- }
- using VkHandle::operator=;
-
- static std::vector< CommandBuffer > New(const CommandPool& pool, bool isPrimary, uint32_t count);
- static CommandBuffer New(const CommandPool& pool, bool isPrimary);
-
- vk::CommandBuffer GetVkBuffer() const;
- const CommandPool& GetCommandPool() const;
- std::thread::id GetThreadId() const;
-
- CommandBufferState GetCommandBufferState() const;
-
- // operator -> allows to record commands directly into Vulkan command buffer
- const vk::CommandBuffer* operator->() const;
-
- bool Begin(bool oneTimeSubmit, bool renderPassContinue = false, bool simultaneousUse = false);
- bool End();
- bool Free();
- bool Reset();
-
- CommandBufferState GetState() const;
-};
-}
-}
-}
-
-#endif // DALI_CORE_GRAPHICS_VULKAN_COMMAND_BUFFER_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/command-pool.h>
-#include <dali/graphics/vulkan/physical-device.h>
-#include <dali/graphics/vulkan/logical-device.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-namespace Vulkan
-{
-
-
-class CommandPoolImpl : public VkObject
-{
-public:
- CommandPoolImpl(const LogicalDevice& device, QueueType type, bool isExclusive, bool createTransient,
- bool createResetCommandBuffer)
- : VkObject{},
- mDevice{ device }, mExclusive{ isExclusive },
- mResetFlag{ createResetCommandBuffer }, mTransientFlag{ createTransient },
- mQueueType{ type }
- {
- }
-
- virtual ~CommandPoolImpl() {};
-
- bool Initialise();
-
- const LogicalDevice& GetLogicalDevice() const
- {
- return mDevice;
- }
-
- // vk objects getters
-public:
-
- const vk::CommandPool GetCommandPool() const
- {
- return mCommandPool;
- }
-
- const vk::CommandPoolCreateInfo& GetCommandPoolCreateInfo() const
- {
- return mCreateInfo;
- }
-
- bool IsExclusive() const
- {
- return mExclusive;
- }
-
- bool IsTransient() const
- {
- return mTransientFlag;
- }
-
- bool IsResetFlag() const
- {
- return mResetFlag;
- }
-
- QueueType GetQueueType() const
- {
- return mQueueType;
- }
-
- std::vector< CommandBuffer > AllocateCommandBuffers(uint32_t count, bool primary);
-
-private:
-
- LogicalDevice mDevice { nullptr };
-
- // vulkan specific
- vk::CommandPool mCommandPool{nullptr};
- vk::CommandPoolCreateInfo mCreateInfo{};
-
- std::thread::id mThreadId; // used if exclusive
-
- // queue properties
- bool mExclusive{false};
- bool mResetFlag{false};
- bool mTransientFlag{false};
-
- QueueType mQueueType;
-};
-
-bool CommandPoolImpl::Initialise()
-{
- auto vkDevice = mDevice.GetVkDevice();
- auto phDevice = mDevice.GetPhysicalDevice();
-
- vk::CommandPoolCreateFlags flags{};
- if( mResetFlag )
- {
- flags |= vk::CommandPoolCreateFlagBits::eResetCommandBuffer;
- }
- if( mTransientFlag )
- {
- flags |= vk::CommandPoolCreateFlagBits::eTransient;
- }
-
- vk::CommandPoolCreateInfo info;
-
- info.setQueueFamilyIndex( phDevice.GetQueueFamilyIndex( mQueueType) );
- info.flags = flags;
- mCreateInfo = info;
-
- VkAssertCall( vkDevice.createCommandPool( &info, mDevice.GetVkAllocator(), &mCommandPool ) );
-
- VkLog("[VULKAN] CommandPoolImpl::Initialise() created!");
-
- return true;
-}
-
-std::vector< CommandBuffer > CommandPoolImpl::AllocateCommandBuffers(uint32_t count, bool primary)
-{
- return std::move(CommandBuffer::New( CommandPool(this), primary, count ));
-}
-
-CommandPool CommandPool::New(const LogicalDevice& device, QueueType type, bool isExclusive,
- bool createTransient, bool createResetCommandBuffer)
-{
- auto impl = new CommandPoolImpl(device, type, isExclusive, createTransient, createResetCommandBuffer);
- CommandPool retval( impl );
- if(!impl->Initialise())
- {
- retval = nullptr;
- }
- return retval;
-}
-
-
-// Implementation getter
-namespace
-{
-CommandPoolImpl* GetImpl( CommandPool* pool )
-{
- return static_cast<CommandPoolImpl*>(pool->GetObject());
-}
-CommandPoolImpl* GetImpl( const CommandPool* pool )
-{
- return static_cast<CommandPoolImpl*>(pool->GetObject());
-}
-}
-bool CommandPool::Initialise()
-{
- return GetImpl(this)->Initialise();
-}
-
-const vk::CommandPool CommandPool::GetCommandPool() const
-{
- return GetImpl(this)->GetCommandPool();
-}
-
-const vk::CommandPoolCreateInfo& CommandPool::GetVkCommandPoolCreateInfo() const
-{
- return GetImpl(this)->GetCommandPoolCreateInfo();
-}
-
-const LogicalDevice& CommandPool::GetLogicalDevice() const
-{
- return GetImpl(this)->GetLogicalDevice();
-}
-
-std::thread::id CommandPool::GetThreadId() const
-{
- //return GetImplementation<CommandPoolImpl>(this)->mThreadId;
- return std::thread::id();
-}
-
-void CommandPool::ThreadAttach()
-{
-
-}
-
-void CommandPool::ThreadDetach()
-{
-
-}
-
-
-std::vector< CommandBuffer > CommandPool::AllocateCommandBuffers(uint32_t count, bool primary)
-{
- return std::move(GetImpl(this)->AllocateCommandBuffers( count, primary ));
-}
-
-CommandBuffer CommandPool::AllocateCommandBuffer(bool primary)
-{
- return GetImpl(this)->AllocateCommandBuffers( 1, primary )[0];
-}
-
-
-}
-}
-}
+++ /dev/null
-#ifndef DALI_CORE_VULKAN_COMMAND_POOL_H
-#define DALI_CORE_VULKAN_COMMAND_POOL_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/command-buffer.h>
-#include <dali/graphics/vulkan/common.h>
-#include <thread>
-
-namespace Dali
-{
-namespace Graphics
-{
-namespace Vulkan
-{
-class LogicalDevice;
-
-//using VulkanCommandBufferArray = std::vector< VulkanCommandBuffer >;
-
-class CommandPool : public VkHandle
-{
-public:
- CommandPool(VkObject* impl = nullptr) : VkHandle{impl}
- {
- }
- using VkHandle::operator=;
-
- static CommandPool New(const LogicalDevice& context, QueueType type, bool isExclusive,
- bool createTransient, bool createResetCommandBuffer);
-
- bool Initialise();
-
- // attaching to thread will make sure that any attempt of using pool on the
- // wrong thread will assert
- void ThreadAttach();
- void ThreadDetach();
-
- const vk::CommandPool GetCommandPool() const;
- const LogicalDevice& GetLogicalDevice() const;
- const vk::CommandPoolCreateInfo& GetVkCommandPoolCreateInfo() const;
- std::thread::id GetThreadId() const;
-
- std::vector< CommandBuffer > AllocateCommandBuffers(uint32_t count, bool primary);
- CommandBuffer AllocateCommandBuffer(bool primary);
-};
-}
-}
-}
-
-#endif //DALI_CORE_VULKANCOMMANDPOOL_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/command-queue.h>
-#include <dali/graphics/vulkan/logical-device.h>
-#include <dali/graphics/vulkan/physical-device.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-namespace Vulkan
-{
-class QueueImpl : public VkObject
-{
-public:
- QueueImpl(const LogicalDevice& device, QueueType type, uint32_t queueIndex)
- : VkObject{}, mDevice{device}, mType{type}, mQueue{nullptr}, mQueueIndex{queueIndex}
- {
- }
-
- bool Initialise()
- {
- auto phDevice = mDevice.GetPhysicalDevice();
- auto vkDevice = mDevice.GetVkDevice();
-
- uint32_t familyIndex = static_cast< uint32_t >(phDevice.GetQueueFamilyIndex(mType));
- vkDevice.getQueue(familyIndex, mQueueIndex, &mQueue);
- return true;
- }
-
- bool Submit(const std::vector< CommandBuffer >& buffers, vk::Fence fence = nullptr)
- {
- return Submit(buffers.data(), static_cast< uint32_t >(buffers.size()), nullptr, 0, nullptr, 0, nullptr, fence);
- }
-
- bool Submit(const CommandBuffer* pBuffers, const uint32_t bufferCount,
- const vk::Semaphore* pWaitSemaphores, const uint32_t waitSemaphoreCount,
- const vk::Semaphore* pSignalSemaphores, const uint32_t signalSemaphoreCount,
- const vk::PipelineStageFlags* pWaitDstStageFlags, vk::Fence fence)
- {
- // todo make temporary copy more efficient
- auto vkBuffers = std::vector< vk::CommandBuffer >(bufferCount);
- for(uint32_t index = 0; index < bufferCount; ++index)
- {
- vkBuffers[index] = pBuffers[index].GetVkBuffer();
- }
-
- if(fence)
- {
- mDevice.GetVkDevice().resetFences(1, &fence);
- }
-
- vk::SubmitInfo info;
- info.setCommandBufferCount(bufferCount)
- .setPCommandBuffers(vkBuffers.data())
- .setWaitSemaphoreCount(waitSemaphoreCount)
- .setPWaitSemaphores(pWaitSemaphores)
- .setSignalSemaphoreCount(signalSemaphoreCount)
- .setPSignalSemaphores(pSignalSemaphores)
- .setPWaitDstStageMask(pWaitDstStageFlags);
-
- if(VkTestCall(mQueue.submit(1, &info, fence)) != vk::Result::eSuccess)
- {
- return false;
- }
- return true;
- }
-
- void WaitIdle() const
- {
- mQueue.waitIdle();
- }
-
- LogicalDevice mDevice;
- QueueType mType;
- vk::Queue mQueue;
- uint32_t mQueueIndex;
-};
-
-namespace
-{
-QueueImpl* GetImpl(const CommandQueue* queue)
-{
- return static_cast< QueueImpl* >(queue->GetObject());
-}
-QueueImpl* GetImpl(CommandQueue* queue)
-{
- return static_cast< QueueImpl* >(queue->GetObject());
-}
-}
-
-CommandQueue CommandQueue::Get(const LogicalDevice& device, QueueType type, uint32_t queueIndex)
-{
- auto impl = new QueueImpl(device, type, queueIndex);
- impl->Initialise();
- CommandQueue retval(impl);
- return retval;
-}
-
-vk::Queue CommandQueue::GetVkQueue() const
-{
- return GetImpl(this)->mQueue;
-}
-
-uint32_t CommandQueue::GetIndex() const
-{
- return GetImpl(this)->mQueueIndex;
-}
-
-QueueType CommandQueue::GetType() const
-{
- return GetImpl(this)->mType;
-}
-
-bool CommandQueue::Submit(const std::vector< CommandBuffer >& buffers, vk::Fence fence)
-{
- return GetImpl(this)->Submit(buffers, fence);
-}
-
-bool CommandQueue::Submit(const CommandBuffer* buffers, uint32_t count, vk::Fence fence)
-{
- return GetImpl(this)->Submit(buffers, count, nullptr, 0, nullptr, 0, nullptr, fence);
-}
-
-bool CommandQueue::Submit(const CommandBuffer* pBuffers, const uint32_t bufferCount,
- const vk::Semaphore* pWaitSemaphores, const uint32_t waitSemaphoreCount,
- const vk::Semaphore* pSignalSemaphores, const uint32_t signalSemaphoreCount,
- const vk::PipelineStageFlags* pWaitDstStageFlags, vk::Fence fence) const
-{
- return GetImpl(this)->Submit(pBuffers, bufferCount, pWaitSemaphores, waitSemaphoreCount,
- pSignalSemaphores, signalSemaphoreCount, pWaitDstStageFlags, fence);
-}
-
-void CommandQueue::WaitIdle() const
-{
- GetImpl(this)->WaitIdle();
-}
-}
-}
-}
\ No newline at end of file
+++ /dev/null
-#ifndef DALI_CORE_GRAPHICS_VULKAN_COMMAND_QUEUE_H
-#define DALI_CORE_GRAPHICS_VULKAN_COMMAND_QUEUE_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/common.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-namespace Vulkan
-{
-class CommandBuffer;
-class LogicalDevice;
-
-class CommandQueue : public VkHandle
-{
-public:
- CommandQueue(VkObject* impl = nullptr) : VkHandle{impl}
- {
- }
- using VkHandle::operator=;
-
- static CommandQueue Get(const LogicalDevice& device, QueueType type, uint32_t queueIndex);
-
- vk::Queue GetVkQueue() const;
- uint32_t GetIndex() const;
- QueueType GetType() const;
-
- bool Submit(const CommandBuffer* buffers, uint32_t count, vk::Fence fence);
- bool Submit(const std::vector< CommandBuffer >& buffers, vk::Fence fence);
- bool Submit(const CommandBuffer* pBuffers, const uint32_t bufferCount,
- const vk::Semaphore* pWaitSemaphores, const uint32_t waitSemaphoreCount,
- const vk::Semaphore* pSignalSemaphores, const uint32_t signalSemaphoreCount,
- const vk::PipelineStageFlags* pWaitDstStageFlags, vk::Fence fence) const;
-
- void WaitIdle() const;
-};
-}
-}
-}
-
-#endif // DALI_CORE_GRAPHICS_VULKAN_COMMAND_QUEUE_H
+++ /dev/null
-#ifndef DALI_CORE_GRAPHICS_VULKAN_COMMON_H
-#define DALI_CORE_GRAPHICS_VULKAN_COMMON_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 <vulkan/vulkan.hpp>
-
-#include <cassert>
-#include <cinttypes>
-#include <memory>
-
-namespace Dali
-{
-namespace Graphics
-{
-namespace Vulkan
-{
-void VkLog(const char* format, ...);
-
-#define OBJECT_HANDLE(TYPE)\
-public:\
- TYPE( VkObject* object = nullptr ) : VkHandle{ object }{}\
- using VkHandle::operator=;
-
-
-#define VkAssert(var, message) \
- { \
- if(var.result != vk::Result::eSuccess) \
- { \
- Dali::Graphics::Vulkan::VkLog("[Assert] %s", message); \
- assert(var.result == vk::Result::eSuccess); \
- } \
- }
-
-#define VkAssertCall(call) \
- { \
- const auto& _result = call; \
- if(_result != vk::Result::eSuccess) \
- { \
- Dali::Graphics::Vulkan::VkLog("[VkAssertCall] %s:%d: %s", __FILE__, __LINE__, #call); \
- assert(_result == vk::Result::eSuccess); \
- } \
- }
-
-#define VkAssertCallMsg(call, msg) \
- { \
- auto _result = call; \
- if(_result != vk::Result::eSuccess) \
- { \
- Dali::Graphics::Vulkan::VkLog("[VkAssertCall] %s:%d: %s, %s", __FILE__, __LINE__, #call, msg); \
- assert(_result == vk::Result::eSuccess); \
- } \
- }
-
-inline vk::Result VkTestCallFn(vk::Result result, const char* file, const char* call, int line)
-{
- if(result != vk::Result::eSuccess)
- {
- Dali::Graphics::Vulkan::VkLog("[VkTestCall] %s:%d: %s -> Result = %d", file, line, call, static_cast< int >(result));
- }
- return result;
-}
-
-#define VkTestCall(call) VkTestCallFn(call, __FILE__, #call, __LINE__)
-#define VkTestBool(call) (vk::Result::eSuccess == VkTestCallFn(call, __FILE__, #call, __LINE__))
-}
-
-// helper template to create relation between flags and bits
-template< typename BitType, typename FlagType = uint32_t >
-struct BitFlags
-{
- BitFlags() = default;
-
- BitFlags(FlagType f) : flags(f)
- {
- }
-
- BitFlags(const BitType& bit)
- {
- flags = static_cast< FlagType >(bit);
- }
-
- operator FlagType()
- {
- return flags;
- }
-
- bool operator==(FlagType srcFlags) const
- {
- return srcFlags == flags;
- }
-
- bool operator!=(const FlagType& srcFlags) const
- {
- return srcFlags != flags;
- }
-
- BitFlags operator|(const BitType& bit)
- {
- return BitFlags(flags | static_cast< FlagType >(bit));
- }
-
- BitFlags& operator|=(const BitType& bit)
- {
- flags |= static_cast< FlagType >(bit);
- return *this;
- }
-
- BitFlags operator&(const BitFlags& rhs) const
- {
- return FlagType{(rhs.flags & flags)};
- }
-
- BitFlags operator&(unsigned int rhs) const
- {
- return BitFlags{(rhs & flags)};
- }
-
- FlagType flags{0};
-};
-
-using ExtensionNameList = std::vector< const char* >;
-using LayerNameList = std::vector< const char* >;
-
-// common for adaptor
-enum class ValidationLayerBit2
-{
- NONE = 0,
- SCREENSHOT = (1 << 0),
- PARAMETER_VALIDATION = (1 << 1),
- VKTRACE = (1 << 2),
- MONITOR = (1 << 3),
- SWAPCHAIN = (1 << 4),
- THREADING = (1 << 5),
- API_DUMP = (1 << 6),
- OBJECT_TRACKER = (1 << 7),
- CORE_VALIDATION = (1 << 8),
- UNIQUE_OBJECTS = (1 << 9),
- STANDARD_VALIDATION = (1 << 10),
- ALL = 0xFFFF
-};
-
-enum class ValidationChannelBit
-{
- NONE = 0,
- INFORMATION = (1 << 0),
- WARNING = (1 << 1),
- PERFORMANCE_WARNING = (1 << 2),
- ERROR = (1 << 3),
- DEBUG = (1 << 4),
- ALL = 0xFF
-};
-
-using ValidationLayerFlags2 = BitFlags< ValidationLayerBit2 >;
-using ValidationChannelFlags = BitFlags< ValidationChannelBit >;
-
-enum class PhysicalDeviceBit
-{
- // physical device type
- ANY = 0,
- DISCRETE = (1 << 0),
- INTEGRATED = (1 << 1)
-};
-
-using PhysicalDeviceFlags = BitFlags< PhysicalDeviceBit >;
-
-/// -----------------------------------------------------
-// vulkan only some sort of managed objects support
-//
-class VkObject
-{
-public:
- VkObject() = default;
- virtual ~VkObject() = default;
-
- uint32_t RetainRef()
- {
- return ++mObjectRefCount;
- }
-
- uint32_t ReleaseRef()
- {
- return --mObjectRefCount;
- }
-
- uint32_t GetRefCount()
- {
- return mObjectRefCount;
- }
-
- // handles releasing of vulkan object before being deleted
- // or moved to discard queue
- virtual bool OnSafeDelete()
- {
- return true;
- }
-
-private:
- uint32_t mObjectRefCount{0};
-};
-
-template< typename OBJECT >
-class VkHandleBase
-{
-public:
- VkHandleBase() = default;
- VkHandleBase(OBJECT* ptr)
- {
- mObject = ptr;
- if(mObject)
- {
- static_cast< VkObject * >(mObject)->RetainRef();
- }
- }
-
- VkHandleBase(const VkHandleBase& handle)
- {
- if(handle.mObject)
- {
- static_cast< VkObject * >(handle.mObject)->RetainRef();
- }
-
- mObject = handle.mObject;
- }
-
- virtual ~VkHandleBase()
- {
- if(mObject)
- {
- static_cast< VkObject* >(mObject)->ReleaseRef();
- TrySafeDelete();
- }
- }
-
- VkHandleBase& operator=(OBJECT* ptr)
- {
- if(mObject == ptr)
- {
- return *this;
- }
- if(mObject)
- {
- static_cast< VkObject* >(mObject)->ReleaseRef();
- TrySafeDelete();
- }
- if(ptr)
- {
- static_cast< VkObject * >(ptr)->RetainRef();
- }
- mObject = ptr;
- return *this;
- }
-
- VkHandleBase& operator=(const VkHandleBase& handle)
- {
- if(handle.mObject == mObject)
- {
- return *this;
- }
- if(mObject)
- {
- static_cast< VkObject* >(mObject)->ReleaseRef();
- TrySafeDelete();
- }
- mObject = handle.mObject;
- if(mObject)
- {
- static_cast< VkObject * >(mObject)->RetainRef();
- }
- return *this;
- }
-
- OBJECT* GetObject() const
- {
- return mObject;
- }
-
- operator bool() const
- {
- return mObject != nullptr;
- }
-
- bool operator!() const
- {
- return mObject == nullptr;
- }
-
- void Reset()
- {
- if(mObject)
- {
- static_cast< VkObject * >(mObject)->ReleaseRef();
- }
- TrySafeDelete();
- mObject = nullptr;
- }
-
- bool TrySafeDelete()
- {
- if(!static_cast< VkObject* >(mObject)->GetRefCount())
- {
- if(static_cast< VkObject* >(mObject)->OnSafeDelete())
- {
- delete mObject;
- }
- }
- // todo: deletion didn't go well, should be asserted?
- return false;
- }
-
- template< typename T >
- T Cast()
- {
- return T(dynamic_cast< OBJECT* >(mObject));
- }
-
-protected:
- OBJECT* mObject{nullptr};
-};
-
-using VkHandle = VkHandleBase< VkObject >;
-
-enum class QueueType : uint32_t
-{
- GRAPHICS = 0u,
- COMPUTE = 1u,
- TRANSFER = 2u,
- SPARSE_BINDING = 3u,
- PRESENT = 4u,
- END
-};
-}
-}
-
-#endif //DALI_CORE_GRAPHICS_VULKAN_COMMON_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/device-memory.h>
-#include <dali/graphics/vulkan/logical-device.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-namespace Vulkan
-{
-
-class DeviceMemoryImpl : public VkObject
-{
-public:
- DeviceMemoryImpl(const LogicalDevice& device, const vk::MemoryAllocateInfo& allocateInfo);
-
- bool Initialise();
-
- virtual bool OnSafeDelete();
-
- const LogicalDevice& GetLogicalDevice() const
- {
- return mDevice;
- }
-
- const vk::DeviceMemory& GetVkDeviceMemory() const
- {
- return mMemory;
- }
-
- size_t GetSize() const
- {
- return mSize;
- }
-
- void* Map(size_t offset, size_t range);
-
- void Unmap();
-
- void Flush(size_t offset, size_t range);
-
-private:
- LogicalDevice mDevice{nullptr};
- vk::MemoryAllocateInfo mAllocateInfo;
- vk::DeviceMemory mMemory{nullptr};
- size_t mSize{0u};
- void* mMappedPtr{nullptr};
-};
-
-// Implementation
-
-DeviceMemoryImpl::DeviceMemoryImpl(const LogicalDevice& device, const vk::MemoryAllocateInfo& allocateInfo)
-: mDevice(device), mAllocateInfo(allocateInfo), mMemory(nullptr), mSize(0u)
-{
-}
-
-bool DeviceMemoryImpl::Initialise()
-{
- auto vkDevice = mDevice.GetVkDevice();
- auto vkAllocator = mDevice.GetVkAllocator();
-
- VkAssertCall(vkDevice.allocateMemory(&mAllocateInfo, vkAllocator, &mMemory));
-
- mSize = mAllocateInfo.allocationSize;
- return true;
-}
-
-bool DeviceMemoryImpl::OnSafeDelete()
-{
- if(mMemory)
- {
- mDevice.GetVkDevice().freeMemory(mMemory, mDevice.GetVkAllocator());
- return true;
- }
- return false;
-}
-
-void* DeviceMemoryImpl::Map(size_t offset, size_t range)
-{
- assert(mMappedPtr == nullptr && "Device memory must not be previously mapped!");
- void *ptr = nullptr;
- if (VkTestCall(mDevice.GetVkDevice()
- .mapMemory(mMemory, offset, range, vk::MemoryMapFlags(), &ptr)) !=
- vk::Result::eSuccess)
- {
- return nullptr;
- }
- mMappedPtr = ptr;
- return ptr;
-}
-
-void DeviceMemoryImpl::Unmap()
-{
- assert(mMappedPtr != nullptr && "Device memory must be mapped!");
- mDevice.GetVkDevice().unmapMemory(mMemory);
- mMappedPtr = nullptr;
-}
-
-void DeviceMemoryImpl::Flush(size_t offset, size_t size)
-{
- vk::MappedMemoryRange range;
- range.setOffset(offset).setMemory(mMemory).setSize(size);
- mDevice.GetVkDevice().flushMappedMemoryRanges(1, &range);
-}
-
-// Handle
-
-namespace
-{
-DeviceMemoryImpl* GetImpl(DeviceMemory* handle)
-{
- return static_cast< DeviceMemoryImpl* >(handle->GetObject());
-}
-
-DeviceMemoryImpl* GetImpl(const DeviceMemory* handle)
-{
- return static_cast< DeviceMemoryImpl* >(handle->GetObject());
-}
-}
-
-DeviceMemory DeviceMemory::New(class LogicalDevice& device, const vk::MemoryAllocateInfo& allocateInfo)
-{
- auto impl = new DeviceMemoryImpl(device, allocateInfo);
- if(impl->Initialise())
- {
- return impl;
- }
- return nullptr;
-}
-
-const LogicalDevice& DeviceMemory::GetLogicalDevice() const
-{
- return GetImpl(this)->GetLogicalDevice();
-}
-
-const vk::DeviceMemory& DeviceMemory::GetVkDeviceMemory() const
-{
- return GetImpl(this)->GetVkDeviceMemory();
-}
-
-const vk::DeviceMemory& DeviceMemory::operator*() const
-{
- return GetImpl(this)->GetVkDeviceMemory();
-}
-
-size_t DeviceMemory::GetSize() const
-{
- return GetImpl(this)->GetSize();
-}
-
-void* DeviceMemory::Map(size_t offset, size_t range)
-{
- return GetImpl(this)->Map(offset, range);
-}
-
-void DeviceMemory::Unmap()
-{
- GetImpl(this)->Unmap();
-}
-
-void DeviceMemory::Flush(size_t offset, size_t range)
-{
- GetImpl(this)->Flush(offset, range);
-}
-
-void DeviceMemory::Flush()
-{
- GetImpl(this)->Flush(0, VK_WHOLE_SIZE);
-}
-
-} // Vulkan
-} // Graphics
-} // Dali
+++ /dev/null
-#ifndef DALI_CORE_GRAPHICS_VULKAN_DEVICE_MEMORY_H
-#define DALI_CORE_GRAPHICS_VULKAN_DEVICE_MEMORY_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/common.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-namespace Vulkan
-{
-
-class DeviceMemory : public VkHandle
-{
-public:
- DeviceMemory(VkObject* object = nullptr) : VkHandle{object}
- {
- }
-
- using VkHandle::operator=;
-
- /**
- * New DeviceMemory associated with logical device
- * @param device
- * @param allocateInfo
- * @return
- */
- static DeviceMemory New(class LogicalDevice &device, const vk::MemoryAllocateInfo &allocateInfo);
-
- /**
- * Map memory ( only if host visible )
- * @param offset
- * @param range
- * @return
- */
- void *Map(size_t offset, size_t range);
-
- /**
- * Unmap previously mapped memory
- */
- void Unmap();
-
- /**
- * Flush device memory in selected range
- * @param offset
- * @param range
- */
- void Flush(size_t offset, size_t range);
-
- /**
- * Flush entire block allocated as device memory
- */
- void Flush();
-
- const class LogicalDevice &GetLogicalDevice() const;
- const vk::DeviceMemory & GetVkDeviceMemory() const;
- const vk::DeviceMemory &operator*() const;
- size_t GetSize() const;
-};
-}
-}
-}
-
-#endif // DALI_CORE_GRAPHICS_VULKAN_DEVICE_MEMORY_H
+++ /dev/null
-#ifndef DALI_GRAPHICS_VULKAN_FRAME_STACK
-#define DALI_GRAPHICS_VULKAN_FRAME_STACK
-
-/*
- * 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 <cstdint>
-
-namespace Dali
-{
-namespace Graphics
-{
-namespace Vulkan
-{
-
-using Frame = char*;
-
-/**
- * Simple stack frame-based fixed size allocator ( single sided )
- */
-class Stack
-{
-public:
-
- Stack( uint32_t capacityInBytes )
- {
- mData = new char[capacityInBytes];
- mCurrentPtr = mData;
- mCapacity = capacityInBytes;
- mRecentFrame = nullptr;
- }
-
- ~Stack()
- {
- delete [] mCurrentPtr;
- }
-
- Frame Mark()
- {
- mRecentFrame = mCurrentPtr;
- return mCurrentPtr;
- }
-
- Frame Rollback( Frame frame = nullptr )
- {
- if( !frame )
- {
- if( mRecentFrame )
- {
- mCurrentPtr = mRecentFrame;
- mRecentFrame = nullptr;
- }
- else
- {
- mCurrentPtr = mData;
- }
- }
- return mCurrentPtr;
- }
-
- void RollbackAll()
- {
- mCurrentPtr = mData;
- }
-
- template <typename T>
- T* Alloc( uint32_t count = 1 )
- {
- uintptr_t alignment = alignof(T)-(reinterpret_cast<uintptr_t>(mCurrentPtr)%alignof(T));
- auto result = reinterpret_cast<T*>(mCurrentPtr + alignment);
- if( result >= reinterpret_cast<T*>( mData + mCapacity ) )
- {
- return nullptr;
- }
- mCurrentPtr += sizeof(T) * count;
- return result;
- }
-
- template <typename T, typename... Args>
- T* AllocNew( Args&&... args )
- {
- T* ptr = Alloc<T>(1);
- if(!ptr)
- {
- return nullptr;
- }
- return new(ptr)T(args...);
- }
-
- template <typename T, typename... Args>
- T& AllocNewRef( Args&&... args )
- {
- T* ptr = Alloc<T>(1);
- return *(new(ptr)T(args...));
- }
-
-private:
-
- char* mData { nullptr };
- char* mCurrentPtr { nullptr };
- char* mRecentFrame { nullptr };
- uint32_t mCapacity { 0u };
-};
-
-} // namespace Vulkan
-} // namespace Graphics
-} // namespace Dali
-
-
-#endif //DALI_GRAPHICS_VULKAN_FRAME_STACK
+++ /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 "framebuffer.h"
-#include <dali/graphics/vulkan/logical-device.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-namespace Vulkan
-{
-namespace Internal
-{
-class Framebuffer : public VkObject
-{
-public:
- Framebuffer() = delete;
-
- Framebuffer(const LogicalDevice &device, const vk::FramebufferCreateInfo &info)
- : VkObject{}, mDevice{device}, mCreateInfo(info)
- {
- }
-
- virtual ~Framebuffer() = default;
-
- bool Initialise();
-
- const vk::Framebuffer &GetVkObject() const
- {
- return mFramebuffer;
- }
-
- virtual bool OnSafeDelete() override
- {
- if( mFramebuffer )
- {
- mDevice->destroyFramebuffer(mFramebuffer, mDevice.GetVkAllocator());
- return true;
- }
- return false;
- }
-
-private:
- LogicalDevice mDevice;
-
- vk::FramebufferCreateInfo mCreateInfo {};
- vk::Framebuffer mFramebuffer {nullptr};
-
-
-};
-
-bool Framebuffer::Initialise()
-{
- return VkTestBool(mDevice->createFramebuffer(&mCreateInfo, mDevice.GetVkAllocator(), &mFramebuffer));
-}
-
-}
-
-namespace
-{
-Internal::Framebuffer* GetImpl( const Framebuffer* handle )
-{
- return static_cast<Internal::Framebuffer*>(handle->GetObject());
-}
-
-}
-
-Framebuffer Framebuffer::New(const class LogicalDevice& device, const vk::FramebufferCreateInfo& info)
-{
- auto impl = new Internal::Framebuffer(device, info);
- if(impl->Initialise())
- {
- return impl;
- }
- return nullptr;
-}
-
-const vk::Framebuffer& Framebuffer::operator*() const
-{
- return GetImpl(this)->GetVkObject();
-}
-
-}
-}
-}
\ No newline at end of file
+++ /dev/null
-//
-// Created by adam.b on 03/05/17.
-//
-
-#include <dali/graphics/vulkan/image-view.h>
-#include <dali/graphics/vulkan/image.h>
-namespace Dali
-{
-namespace Graphics
-{
-namespace Vulkan
-{
-namespace Internal
-{
-class ImageView : public VkObject
-{
-public:
- ImageView() = delete;
- ImageView( const Image& image, const vk::ImageViewCreateInfo& info );
-
-private:
-
- Image mImage { nullptr };
- vk::ImageViewCreateInfo mCreateInfo { };
-};
-
-ImageView::ImageView( const Image& image, const vk::ImageViewCreateInfo& info )
-: VkObject()
-{
-
-}
-
-}
-
-} // namespace Vulkan
-} // namespace Graphics
-} // namespace Dali
\ No newline at end of file
+++ /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/device-memory.h>
-#include <dali/graphics/vulkan/image.h>
-#include <dali/graphics/vulkan/logical-device.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-namespace Vulkan
-{
-
-class ImageImpl : public VkObject
-{
-public:
- ImageImpl(const LogicalDevice& device, const vk::ImageCreateInfo& createInfo);
-
- /**
- * Initialises new image
- * @return
- */
- bool Initialise();
-
- /**
- * Creates VkImageMemoryBarrier instance in order to change image layout
- * @param newLayout
- * @param srcAccess
- * @param dstAccess
- * @return
- */
- vk::ImageMemoryBarrier CreateLayoutBarrier(vk::ImageLayout newLayout, vk::AccessFlags srcAccess,
- vk::AccessFlags dstAccess);
-
- const vk::Image& GetVkImage() const
- {
- return mImage;
- }
-
- bool BindDeviceMemory(const DeviceMemory& memory, size_t offset);
-
- const vk::ImageCreateInfo& GetImageCreateInfo() const
- {
- return mCreateInfo;
- }
-
- const vk::ImageLayout& GetLayout() const
- {
- return mLayout;
- }
-
- void SetLayout(vk::ImageLayout layout )
- {
- mLayout = layout;
- }
-
-private:
- LogicalDevice mDevice{nullptr};
- vk::ImageCreateInfo mCreateInfo{};
- vk::Image mImage{nullptr};
- vk::ImageLayout mLayout;
-
- DeviceMemory mDeviceMemory{nullptr}; // todo future higher-level wrapper on device memory
- size_t mBoundMemoryOffset{0u};
-};
-
-// Implementation
-
-ImageImpl::ImageImpl(const LogicalDevice& device, const vk::ImageCreateInfo& createInfo)
-: mDevice(device), mCreateInfo(createInfo)
-{
-}
-
-bool ImageImpl::Initialise()
-{
- mLayout = mCreateInfo.initialLayout;
- return VkTestBool(mDevice->createImage(&mCreateInfo, mDevice.GetVkAllocator(), &mImage));
-}
-
-bool ImageImpl::BindDeviceMemory(const DeviceMemory& memory, size_t offset)
-{
- assert(!mDeviceMemory && "DeviceMemory is already set on the Image!");
- if( VkTestBool(mDevice->bindImageMemory(mImage, memory.GetVkDeviceMemory(), offset)) )
- {
- mDeviceMemory = memory;
- mBoundMemoryOffset = offset;
- return true;
- }
- return false;
-}
-
-vk::ImageMemoryBarrier ImageImpl::CreateLayoutBarrier(vk::ImageLayout newLayout,
- vk::AccessFlags srcAccess, vk::AccessFlags dstAccess)
-{
- return vk::ImageMemoryBarrier{};
-}
-
-// Handle
-namespace
-{
-ImageImpl* GetImpl(Image* handle)
-{
- return static_cast< ImageImpl* >(handle->GetObject());
-}
-ImageImpl* GetImpl(const Image* handle)
-{
- return static_cast< ImageImpl* >(handle->GetObject());
-}
-}
-
-Image Image::New(const LogicalDevice& device, const vk::ImageCreateInfo& createInfo)
-{
- auto impl = new ImageImpl(device, createInfo);
- if(impl->Initialise())
- {
- return impl;
- }
- return nullptr;
-}
-
-const vk::Image& Image::GetVkResource() const
-{
- return GetImpl(this)->GetVkImage();
-}
-
-const vk::Image& Image::operator*() const
-{
- return GetImpl(this)->GetVkImage();
-}
-
-bool Image::BindDeviceMemory(const DeviceMemory& memory)
-{
- return GetImpl(this)->BindDeviceMemory(memory, 0);
-}
-
-bool Image::BindDeviceMemory(const DeviceMemory& memory, size_t offset)
-{
- return GetImpl(this)->BindDeviceMemory(memory, offset);
-}
-
-vk::ImageMemoryBarrier Image::GetLayoutChangeBarrier(vk::ImageLayout newLayout,
- vk::AccessFlags srcAccess, vk::AccessFlags dstAccess,
- vk::ImageAspectFlags imageAspect) const
-{
- auto& info = GetImpl(this)->GetImageCreateInfo();
-
- vk::ImageSubresourceRange subresourceRange;
- subresourceRange.setBaseArrayLayer(0)
- .setLayerCount(info.arrayLayers)
- .setAspectMask(imageAspect)
- .setBaseArrayLayer(0)
- .setLevelCount(info.mipLevels)
- .setBaseMipLevel(0);
-
- vk::ImageMemoryBarrier barrier;
- barrier.setNewLayout(newLayout)
- .setOldLayout(GetImpl(this)->GetLayout())
- .setSrcAccessMask(srcAccess)
- .setDstAccessMask(dstAccess)
- .setSubresourceRange(subresourceRange)
- .setImage(GetImpl(this)->GetVkImage());
-
- return barrier;
-}
-
-void Image::SetLayout( vk::ImageLayout layout )
-{
- GetImpl(this)->SetLayout(layout);
-}
-
-vk::ImageLayout Image::GetLayout() const
-{
- return GetImpl(this)->GetLayout();
-}
-}
-}
-}
+++ /dev/null
-#ifndef DALI_CORE_GRAPHICS_VULKAN_IMAGE_H
-#define DALI_CORE_GRAPHICS_VULKAN_IMAGE_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/common.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-namespace Vulkan
-{
-
-class LogicalDevice;
-class DeviceMemory;
-
-class Image : public VkHandle
-{
-public:
-
- Image(VkObject* impl = nullptr ) : VkHandle{impl}{}
- using VkHandle::operator=;
-
- static Image New( const LogicalDevice& device, const vk::ImageCreateInfo& createInfo );
-
- const vk::Image& GetVkResource() const;
- const vk::Image& operator*() const;
-
- vk::ImageLayout GetLayout() const;
- void SetLayout( vk::ImageLayout layout );
- bool BindDeviceMemory( const class DeviceMemory& memory );
- bool BindDeviceMemory( const class DeviceMemory& memory, size_t offset );
-
- vk::ImageMemoryBarrier GetLayoutChangeBarrier( vk::ImageLayout newLayout, vk::AccessFlags srcAccess, vk::AccessFlags dstAccess, vk::ImageAspectFlags imageAspect ) const;
-
-private:
-
-};
-
-
-} // Vulkan
-} // Graphics
-} // Dali
-
-
-#endif // DALI_CORE_GRAPHICS_VULKAN_IMAGE_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/command-queue.h>
-#include <dali/graphics/vulkan/frame-stack.h>
-#include <dali/graphics/vulkan/logical-device.h>
-#include <dali/graphics/vulkan/physical-device.h>
-#include <dali/graphics/vulkan/surface.h>
-#include <dali/graphics/vulkan/swapchain.h>
-namespace Dali
-{
-namespace Graphics
-{
-namespace Vulkan
-{
-
-using QueueArray = std::vector< CommandQueue >;
-using FamilyQueueArray = std::vector< QueueArray >;
-
-class LogicalDeviceImpl : public GraphicsLogicalDeviceBase
-{
-public:
- LogicalDeviceImpl(const PhysicalDevice &physicalDevice)
- : GraphicsLogicalDeviceBase{}, mPhysicalDevice{physicalDevice}, mStack{1024}
- {
- }
-
- const vk::Device &GetDevice() const
- {
- return mDevice;
- }
-
- const PhysicalDevice &GetPhysicalDevice() const
- {
- return mPhysicalDevice;
- }
-
- virtual bool Initialise() override;
-
- virtual GraphicsSwapchain CreateSwapchain(const GraphicsSurface &surface,
- uint32_t bufferCount,
- DepthStencil depthStencil,
- VSyncMode enforceVSync) override;
-
- virtual GraphicsPhysicalDevice GetGraphicsPhysicalDevice() const override
- {
- return GraphicsPhysicalDevice(mPhysicalDevice);
- }
-
- const CommandQueue &GetCommandQueue(uint32_t index, QueueType type) const;
-
- vk::MemoryRequirements GetResourceMemoryRequirements(const vk::Image &image) const;
-
- vk::MemoryRequirements GetResourceMemoryRequirements(const vk::Buffer &buffer) const;
-
- uint32_t GetMemoryIndex(uint32_t memoryTypeBits, vk::MemoryPropertyFlags properties);
-
- template< typename T >
- DeviceMemory AllocateMemory(T object, vk::MemoryPropertyFlags flags, bool doBind);
-
- Image CreateImage(vk::ImageCreateInfo info);
-
- Stack &GetStack(uint32_t stackIndex)
- {
- return mStack;
- }
-
-private:
- vk::Device mDevice{nullptr};
- PhysicalDevice mPhysicalDevice;
-
- ExtensionNameList mEnabledExtensionCStr;
- std::vector< std::string > mEnabledExtensionStr;
- FamilyQueueArray mQueueFamilyArray; // queues allocated per family
- Stack mStack;
- //VulkanCommandPool mTransientPool;
-};
-
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wframe-larger-than="
-bool LogicalDeviceImpl::Initialise()
-{
- auto physDevice = mPhysicalDevice.GetPhysicalDevice();
- auto &features = mPhysicalDevice.GetFeatures();
- auto &stack = GetStack(0);
- stack.Mark();
-
- // for each family allocate all possible queues when creating device
- auto queueInfoArray = std::vector< vk::DeviceQueueCreateInfo >{};
-
- // make a copy of used families and sort
- auto familyIndices = std::vector< int >{};
-
- auto newArray = std::vector< uint32_t >{mPhysicalDevice.GetQueueFamilyIndex(QueueType::GRAPHICS),
- mPhysicalDevice.GetQueueFamilyIndex(QueueType::COMPUTE),
- mPhysicalDevice.GetQueueFamilyIndex(QueueType::TRANSFER),
- mPhysicalDevice.GetQueueFamilyIndex(QueueType::SPARSE_BINDING),
- mPhysicalDevice.GetQueueFamilyIndex(QueueType::PRESENT)};
-
- auto queueFamilyProperties = physDevice.getQueueFamilyProperties();
-
- std::sort(newArray.begin(), newArray.end());
-
- mQueueFamilyArray.resize(newArray.back() + 1);
-
- uint32_t oldIndex = -1u;
- auto priorities = std::vector< float >{};
- for(auto &newIndex : newArray)
- {
- if(newIndex != oldIndex)
- {
- auto &familyProperties = queueFamilyProperties[newIndex];
-
- // set priorities ( all queues have priority 1.0 to keep it simple )
- priorities.resize(familyProperties.queueCount);
- std::fill(priorities.begin(), priorities.end(), 1.0f);
-
- // just resize arrays
- mQueueFamilyArray[newIndex].resize(familyProperties.queueCount);
-
- vk::DeviceQueueCreateInfo queueInfo;
- queueInfo.setQueueCount(familyProperties.queueCount);
- queueInfo.setQueueFamilyIndex(newIndex);
- queueInfo.setPQueuePriorities(priorities.data());
-
- queueInfoArray.emplace_back(queueInfo);
-
- oldIndex = newIndex;
- }
- }
-
- mEnabledExtensionCStr.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
-
- auto deviceInfo = vk::DeviceCreateInfo{};
- deviceInfo.setQueueCreateInfoCount(static_cast< uint32_t >(queueInfoArray.size()));
- deviceInfo.setPQueueCreateInfos(queueInfoArray.data());
- deviceInfo.setEnabledExtensionCount(static_cast< uint32_t >(mEnabledExtensionCStr.size()));
- deviceInfo.setPpEnabledExtensionNames(mEnabledExtensionCStr.data());
- deviceInfo.setPEnabledFeatures(&features);
-
- VkAssertCall(physDevice.createDevice(&deviceInfo, mPhysicalDevice.GetAllocator(), &mDevice));
-
- int familyIndex = 0;
-
- // make a handle of the implementation
- LogicalDevice logicalDevice(this);
- for(auto &&family : mQueueFamilyArray)
- {
- for(uint32_t queueIndex = 0; queueIndex < family.size(); ++queueIndex)
- {
- family[queueIndex] = CommandQueue::Get(logicalDevice, static_cast< QueueType >(familyIndex), queueIndex);
- }
- ++familyIndex;
- }
-
- VkLog("[GraphicsPhysicalDevice] VkDevice created.");
-
- return true;
-}
-#pragma GCC diagnostic pop
-
-GraphicsSwapchain LogicalDeviceImpl::CreateSwapchain(const GraphicsSurface &surface,
- uint32_t bufferCount,
- DepthStencil depthStencil,
- VSyncMode enforceVSync)
-{
- auto swapchain = Swapchain::New(LogicalDevice(this), Surface(surface.GetObject()), bufferCount, depthStencil);
- swapchain.Initialise();
- return swapchain;
-}
-
-const CommandQueue &LogicalDeviceImpl::GetCommandQueue(uint32_t index, QueueType type) const
-{
- return mQueueFamilyArray[mPhysicalDevice.GetQueueFamilyIndex(type)][index];
-}
-
-vk::MemoryRequirements LogicalDeviceImpl::GetResourceMemoryRequirements(const vk::Image &image) const
-{
- return mDevice.getImageMemoryRequirements(image);
-}
-
-vk::MemoryRequirements LogicalDeviceImpl::GetResourceMemoryRequirements(const vk::Buffer &buffer) const
-{
- return mDevice.getBufferMemoryRequirements(buffer);
-}
-
-uint32_t LogicalDeviceImpl::GetMemoryIndex(uint32_t memoryTypeBits, vk::MemoryPropertyFlags properties)
-{
- auto &memprops = mPhysicalDevice.GetMemoryProperties();
- for(uint32_t i = 0; i < memprops.memoryTypeCount; ++i)
- {
- if((memoryTypeBits & (1u << i)) && ((memprops.memoryTypes[i].propertyFlags & properties) == properties))
- {
- return i;
- }
- }
- return -1u;
-}
-
-template< typename T >
-DeviceMemory LogicalDeviceImpl::AllocateMemory(T object, vk::MemoryPropertyFlags flags, bool doBind)
-{
- vk::MemoryRequirements req(GetResourceMemoryRequirements(*object));
-
- vk::MemoryAllocateInfo info;
- uint32_t memoryIndex = GetMemoryIndex(req.memoryTypeBits, flags);
- assert(memoryIndex != -1u && "Wrong memory index!");
- info.setMemoryTypeIndex(memoryIndex).setAllocationSize(req.size);
-
- LogicalDevice deviceHandle(this);
- DeviceMemory memory = DeviceMemory::New(deviceHandle, info);
-
- if(doBind)
- {
- object.BindDeviceMemory(memory);
- }
-
- return memory;
-}
-
-Image LogicalDeviceImpl::CreateImage(vk::ImageCreateInfo info)
-{
- return nullptr;
-}
-
-// End of implementation
-
-//
-
-namespace
-{
-LogicalDeviceImpl *GetImpl(const LogicalDevice *handle)
-{
- return static_cast< LogicalDeviceImpl * >(handle->GetObject());
-}
-
-LogicalDeviceImpl *GetImpl(LogicalDevice *handle)
-{
- return static_cast< LogicalDeviceImpl * >(handle->GetObject());
-}
-
-} //
-
-LogicalDevice LogicalDevice::New(const PhysicalDevice &physicalDevice)
-{
- return LogicalDevice(new LogicalDeviceImpl(physicalDevice));
-}
-
-bool LogicalDevice::Initialise()
-{
- return GetImpl(this)->Initialise();
-}
-
-const vk::Device *LogicalDevice::operator->() const
-{
- auto &vkdevice = GetImpl(this)->GetDevice();
- return &vkdevice;
-}
-
-DeviceMemory LogicalDevice::AllocateImageMemory(const Image &image, vk::MemoryPropertyFlags flags, bool doBind) const
-{
- return GetImpl(this)->AllocateMemory(image, flags, doBind);
-}
-
-DeviceMemory LogicalDevice::AllocateBufferMemory(const Buffer &buffer, vk::MemoryPropertyFlags flags, bool doBind) const
-{
- return GetImpl(this)->AllocateMemory(buffer, flags, doBind);
-}
-
-const vk::Device LogicalDevice::GetVkDevice() const
-{
- return GetImpl(this)->GetDevice();
-}
-
-const PhysicalDevice &LogicalDevice::GetPhysicalDevice() const
-{
- return GetImpl(this)->GetPhysicalDevice();
-}
-
-const vk::AllocationCallbacks *LogicalDevice::GetVkAllocator() const
-{
- return GetImpl(this)->GetPhysicalDevice().GetAllocator();
-}
-
-CommandPool LogicalDevice::CreateCommandPool(QueueType type, bool createTransient, bool createResetCommandBuffer) const
-{
- return CommandPool::New(*this, type, false, createTransient, createResetCommandBuffer);
-}
-
-const CommandQueue &LogicalDevice::GetCommandQueue(uint32_t index, QueueType type) const
-{
- return GetImpl(this)->GetCommandQueue(index, type);
-}
-
-Image LogicalDevice::CreateImage(vk::ImageCreateInfo imageInfo)
-{
- return GetImpl(this)->CreateImage(imageInfo);
-}
-
-Stack &LogicalDevice::GetStack(uint32_t stackIndex)
-{
- return GetImpl(this)->GetStack(stackIndex);
-}
-}
-}
-}
+++ /dev/null
-#ifndef DALI_CORE_GRAPHICS_VULKAN_LOGICAL_DEVICE_H
-#define DALI_CORE_GRAPHICS_VULKAN_LOGICAL_DEVICE_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/graphics-logical-device.h>
-#include <dali/graphics/vulkan/buffer.h>
-#include <dali/graphics/vulkan/command-pool.h>
-#include <dali/graphics/vulkan/device-memory.h>
-#include <dali/graphics/vulkan/image.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-namespace Vulkan
-{
-class PhysicalDevice;
-class CommandQueue;
-class Stack;
-
-class LogicalDevice : public GraphicsLogicalDevice
-{
-public:
- LogicalDevice(GraphicsLogicalDeviceBase* impl = nullptr) : GraphicsLogicalDevice{impl}
- {
- }
-
- using GraphicsLogicalDevice::operator=;
-
- bool Initialise();
-
- const vk::Device GetVkDevice() const;
-
- const vk::AllocationCallbacks* GetVkAllocator() const;
-
- const PhysicalDevice& GetPhysicalDevice() const;
-
- static LogicalDevice New(const PhysicalDevice& physicalDevice);
-
- const vk::Device* operator->() const;
-
- Stack& GetStack(uint32_t stackIndex);
-
- /**
- *
- * @param image
- * @param flags
- * @param doBind
- * @return
- */
- DeviceMemory AllocateImageMemory(const Image& image, vk::MemoryPropertyFlags flags, bool doBind) const;
-
- /**
- *
- * @param buffer
- * @param flags
- * @param doBind
- * @return
- */
- DeviceMemory AllocateBufferMemory(const Buffer& buffer, vk::MemoryPropertyFlags flags, bool doBind) const;
-
- /**
- * Creates new command pool with given settings
- * @param type
- * @param createTransient
- * @param createResetCommandBuffer
- * @return
- */
- CommandPool CreateCommandPool(QueueType type, bool createTransient, bool createResetCommandBuffer) const;
-
- /**
- * Returns one of the pre-allocated command queues or nullptr
- * @param index
- * @param type
- * @return
- */
- const CommandQueue& GetCommandQueue(uint32_t index, QueueType type) const;
-
- // Resources
-
- /*
- * IMAGE
- */
-
- /**
- * Creates Vulkan image object
- * @return
- */
- Image CreateImage2D(uint32_t width, uint32_t height, vk::Format pixelFormat, bool hostVisible, bool bindMemory);
-
- /**
- * Creates Vulkan Image from given VkImageCreateInfo structure
- * @param imageInfo
- * @return
- */
- Image CreateImage(vk::ImageCreateInfo imageInfo);
-};
-
-} // Vulkan
-} // Graphics
-} // Dali
-
-#endif //DALI_CORE_GRAPHICS_VULKAN_LOGICAL_DEVICE_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/common.h>
-#include <dali/graphics/vulkan/logical-device.h>
-#include <dali/graphics/vulkan/physical-device.h>
-#include <dali/graphics/vulkan/surface.h>
-#include <dali/graphics/vulkan/surface/xcb-surface.h>
-#include <dali/graphics/vulkan/surface/xlib-surface.h>
-#include <cstdarg>
-
-namespace Dali
-{
-namespace Graphics
-{
-namespace Vulkan
-{
-
-#define MAX_VKLOG_SIZE (1024 * 1024) // 1mb of log memory per thread
-__thread char* gLogBuffer = nullptr;
-
-// something to replace in the future, maybe
-void VkLog(const char* format, ...)
-{
- if(!gLogBuffer)
- {
- gLogBuffer = new char[MAX_VKLOG_SIZE];
- }
- std::va_list args;
- va_start(args, format);
- vsnprintf(gLogBuffer, MAX_VKLOG_SIZE - 4, format, args);
- puts(gLogBuffer);
- va_end(args);
-}
-
-namespace
-{
-
-template< typename T >
-inline uint32_t Eval(const T& type)
-{
- return static_cast< uint32_t >(type);
-}
-
-// debug callbacks
-#if VULKAN_USE_DEBUG_REPORT_CALLBACK
-VKAPI_ATTR VkBool32 VKAPI_CALL DebugReportCallback(VkDebugReportFlagsEXT flags,
- VkDebugReportObjectTypeEXT objectType,
- uint64_t object,
- size_t location,
- int32_t messageCode,
- const char* pLayerPrefix,
- const char* pMessage,
- void* pUserData)
-{
- VkLog("[VALIDATION:%s]: %s", pLayerPrefix, pMessage);
- return VK_FALSE;
-}
-#endif
-const char* VALIDATION_LAYERS[] = {"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
- nullptr};
-}
-
-/**
- * Internal implementation of the Vulkan instance/physical device
- */
-class PhysicalDeviceImpl : public Integration::GraphicsPhysicalDeviceBase
-{
-public:
- // GraphicsPhysicalDeviceBase
-public:
- virtual bool Initialise(const ExtensionNameList& extensions, const ValidationLayerFlags2& layers);
-
- virtual bool IsExtensionAvailable(const std::string& instanceExtensionName);
-
- virtual bool IsLayerAvailable(const std::string& instanceExtensionName);
-
- virtual GraphicsLogicalDevice CreateLogicalDevice(const ExtensionNameList& enabledExtensions);
-
- virtual bool ChoosePhysicalDevice(const PhysicalDeviceFlags& flags);
-
- virtual void SetValidationDebugChannels(const ValidationChannelFlags& flags)
- {
- }
-
- virtual GraphicsSurface CreateSurface(const NativeSurfaceCreateInfo& info);
-
- void PrepareQueueFamilies();
-
- // Vulkan getters
-public:
- vk::Instance GetInstance() const
- {
- return mVkInstance;
- }
-
- vk::PhysicalDevice GetPhysicalDevice() const
- {
- return mVkPhysicalDevice;
- }
-
- const vk::PhysicalDeviceFeatures& GetFeatures() const
- {
- return mPhysFeatures;
- }
-
- const vk::PhysicalDeviceProperties& GetProperties() const
- {
- return mPhysProperties;
- }
-
- const vk::PhysicalDeviceLimits& GetLimits() const
- {
- return mPhysLimits;
- }
-
- const vk::PhysicalDeviceMemoryProperties& GetMemoryProperties() const
- {
- return mPhysMemoryProperties;
- }
-
- const std::string& GetName() const
- {
- return mPhysName;
- }
-
- const std::string& GetVendorName() const
- {
- return mPhysVendorName;
- }
-
- const vk::AllocationCallbacks* GetAllocator() const
- {
- return mAllocatorCallbacks;
- }
-
- uint32_t GetQueueFamilyIndex(QueueType type) const
- {
- return mQueueFamilyIndex[Eval(type)];
- }
-
-private:
- // Vulkan instance extension properties list
- std::vector< vk::ExtensionProperties > mInstanceExtensionProperties;
-
- // Vulkan device extension properties list
- std::vector< vk::ExtensionProperties > mDeviceExtensionProperties;
-
- // Vulkan instance layer properties list
- std::vector< vk::LayerProperties > mInstanceLayerProperties;
-
- // Allocators
- vk::AllocationCallbacks* mAllocatorCallbacks{nullptr};
-
- // Instance
- vk::Instance mVkInstance{nullptr};
-
- // Physical device
- vk::PhysicalDevice mVkPhysicalDevice{nullptr};
- vk::PhysicalDeviceFeatures mPhysFeatures{};
- vk::PhysicalDeviceProperties mPhysProperties{};
- vk::PhysicalDeviceMemoryProperties mPhysMemoryProperties{};
- vk::PhysicalDeviceType mPhysType;
- vk::PhysicalDeviceLimits mPhysLimits;
- uint32_t mPhysApiVersion{0};
- uint32_t mPhysDriverVersion{0};
- std::string mPhysName;
- std::string mPhysVendorName;
- bool mPhysIsDiscrete{false};
-
- // Queue families
- std::vector< vk::QueueFamilyProperties > mQueueFamilyProperties;
- std::array< uint32_t, static_cast< uint32_t >(QueueType::END) > mQueueFamilyIndex;
-
- // todo add surface type register
-};
-
-bool PhysicalDeviceImpl::IsExtensionAvailable(const std::string& instanceExtensionName)
-{
- if(mInstanceExtensionProperties.empty())
- {
- auto result = vk::enumerateInstanceExtensionProperties();
- if(result.result != vk::Result::eSuccess)
- {
- // todo no vulkan support????
- return false;
- }
- mInstanceExtensionProperties = std::move(result.value);
- }
-
- for(auto&& ext : mInstanceExtensionProperties)
- {
- if(instanceExtensionName == ext.extensionName)
- {
- return true;
- }
- }
- return false;
-}
-
-bool PhysicalDeviceImpl::IsLayerAvailable(const std::string& instanceLayerName)
-{
- if(mInstanceLayerProperties.empty())
- {
- auto result = vk::enumerateInstanceLayerProperties();
- if(result.result != vk::Result::eSuccess)
- {
- // todo no vulkan support????
- return false;
- }
- mInstanceLayerProperties = std::move(result.value);
- }
-
- for(auto&& ext : mInstanceLayerProperties)
- {
- if(instanceLayerName == ext.layerName)
- {
- return true;
- }
- }
- return false;
-}
-
-bool PhysicalDeviceImpl::Initialise(const ExtensionNameList& extensions, const ValidationLayerFlags2& layers)
-{
- // make a copy and add debug report extension in case there are any
- // validation layers listed
- auto extCopy = ExtensionNameList{extensions};
- if(layers != 0u)
- {
- extCopy.emplace_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
- }
-
- // add validation layers
- LayerNameList layerTable;
- auto retval = LayerNameList{};
-
- for(uint32_t bit = 0; VALIDATION_LAYERS[bit]; ++bit)
- {
- if(layers & (1u << bit))
- {
- layerTable.emplace_back(VALIDATION_LAYERS[bit]);
- }
- }
-
- vk::InstanceCreateInfo info;
- info.setEnabledExtensionCount(static_cast<uint32_t>(extCopy.size()))
- .setPpEnabledExtensionNames(extCopy.data())
- .setPApplicationInfo(nullptr)
- .setPpEnabledLayerNames(layerTable.empty() ? nullptr : layerTable.data())
- .setEnabledLayerCount(static_cast<uint32_t>(layerTable.size()));
-
- return (vk::Result::eSuccess == VkTestCall(vk::createInstance(&info, mAllocatorCallbacks, &mVkInstance)));
-}
-
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wframe-larger-than="
-bool PhysicalDeviceImpl::ChoosePhysicalDevice(const PhysicalDeviceFlags& flags)
-{
- auto preferredDiscrete = flags & PhysicalDeviceBit::DISCRETE ? true : false;
-
- // set preferred device type
- const vk::PhysicalDeviceType preferredType =
- preferredDiscrete ? vk::PhysicalDeviceType::eDiscreteGpu : vk::PhysicalDeviceType::eIntegratedGpu;
-
- // set fallback device type
- const vk::PhysicalDeviceType fallbackType =
- preferredDiscrete ? vk::PhysicalDeviceType::eIntegratedGpu : vk::PhysicalDeviceType::eDiscreteGpu;
-
- auto result = mVkInstance.enumeratePhysicalDevices();
- VkAssertCallMsg(result.result, "No Vulkan devices found!");
-
- auto GPUs = result.value;
- auto currentGPU = GPUs.front();
- auto currentGPUProps = currentGPU.getProperties();
-
- // select discreet over integrated
- for(auto&& gpu : GPUs)
- {
- auto gpuProperties = gpu.getProperties();
- if((currentGPUProps.deviceType != preferredType && gpuProperties.deviceType == preferredType) ||
- (currentGPUProps.deviceType != preferredType && gpuProperties.deviceType == fallbackType))
- {
- currentGPU = gpu;
- currentGPUProps = gpuProperties;
- }
- }
-
- // make sure selected GPU is THE REAL GPU not a blanket or refrigerator
- if(currentGPUProps.deviceType != preferredType && currentGPUProps.deviceType != fallbackType)
- {
- // error
- return false;
- }
-
- // store GPU data
- // fixme
- auto& gpu = currentGPU;
- auto& gpuProperties = currentGPUProps;
- auto gpuMemoryProperties = currentGPU.getMemoryProperties();
- auto gpuFeatures = currentGPU.getFeatures();
-
- auto deviceExtensionProperties = gpu.enumerateDeviceExtensionProperties();
- mDeviceExtensionProperties = deviceExtensionProperties.value;
-
- auto queueFamilyProperties = gpu.getQueueFamilyProperties();
-
- // collect all physical device related information
- mPhysIsDiscrete = preferredDiscrete;
- mVkPhysicalDevice = gpu;
- mPhysProperties = gpuProperties;
- mPhysFeatures = gpuFeatures;
- mPhysMemoryProperties = gpuMemoryProperties;
- mPhysLimits = mPhysProperties.limits;
- mPhysType = mPhysProperties.deviceType;
-
- // fill common stuff
- mPhysName = mPhysProperties.deviceName;
-
- switch(mPhysProperties.vendorID)
- {
- case 0x10DE: //nvidia
- mPhysVendorName = "NVIDIA";
- break;
- default:
- mPhysVendorName = "Unknown";
- }
-
- mPhysApiVersion = mPhysProperties.apiVersion;
- mPhysDriverVersion = mPhysProperties.driverVersion;
-
- VkLog("[Vulkan] Found physical device: %s", mPhysName.c_str());
- VkLog("[Vulkan] vendor: %s", mPhysVendorName.c_str());
-
- // prepare queue families
- PrepareQueueFamilies();
-
- return true;
-}
-#pragma GCC diagnostic pop
-
-GraphicsLogicalDevice PhysicalDeviceImpl::CreateLogicalDevice(const ExtensionNameList& enabledExtensions)
-{
- LogicalDevice logicDevice(LogicalDevice::New(this));
- if(!logicDevice.Initialise())
- {
- logicDevice = nullptr;
- }
- return logicDevice;
-}
-
-void PhysicalDeviceImpl::PrepareQueueFamilies()
-{
- uint32_t& familyGraphics{mQueueFamilyIndex[Eval(QueueType::GRAPHICS)]};
- uint32_t& familyTransfer{mQueueFamilyIndex[Eval(QueueType::TRANSFER)]};
- uint32_t& familyCompute{mQueueFamilyIndex[Eval(QueueType::COMPUTE)]};
- uint32_t& familySparseBinding{mQueueFamilyIndex[Eval(QueueType::SPARSE_BINDING)]};
- uint32_t& familyPresent{mQueueFamilyIndex[Eval(QueueType::PRESENT)]};
- familyGraphics = familyTransfer = familyCompute = familySparseBinding = familyPresent = -1u;
-
- mQueueFamilyProperties = mVkPhysicalDevice.getQueueFamilyProperties();
-
- uint32_t queueIndex = 0;
- for(auto&& queueFamily : mQueueFamilyProperties)
- {
- if(familyGraphics == -1u && (queueFamily.queueFlags | vk::QueueFlagBits::eGraphics))
- {
- familyGraphics = queueIndex;
- }
- if(familyTransfer == -1u && (queueFamily.queueFlags | vk::QueueFlagBits::eTransfer))
- {
- familyTransfer = queueIndex;
- }
- if(familyCompute == -1u && (queueFamily.queueFlags | vk::QueueFlagBits::eCompute))
- {
- familyCompute = queueIndex;
- }
- if(familySparseBinding == -1u && (queueFamily.queueFlags | vk::QueueFlagBits::eSparseBinding))
- {
- familySparseBinding = queueIndex;
- }
-
- ++queueIndex;
- }
-}
-
-GraphicsSurface PhysicalDeviceImpl::CreateSurface(const NativeSurfaceCreateInfo& info)
-{
- uint32_t& familyPresent{mQueueFamilyIndex[Eval(QueueType::PRESENT)]};
-
- assert(familyPresent == -1u && "Looks like the surface has been created!");
-
- // should be part of adaptor????
- GraphicsSurface retval{nullptr};
- if(info.surfaceType == NativeSurfaceType::XCB)
- {
- const XcbSurfaceCreateInfo* xcbInfo = reinterpret_cast< const XcbSurfaceCreateInfo* >(&info);
- GraphicsPhysicalDevice physDevice(this);
- retval = Surface::New< XcbSurface >(physDevice, xcbInfo->connection, xcbInfo->window);
- }
- else if(info.surfaceType == NativeSurfaceType::X11)
- {
- const XlibSurfaceCreateInfo* xlibInfo = reinterpret_cast< const XlibSurfaceCreateInfo* >(&info);
- GraphicsPhysicalDevice physDevice(this);
- retval = Surface::New< XlibSurface >(physDevice, xlibInfo->display, xlibInfo->window);
- }
- // check surface compatibility against queue families
- uint32_t queueIndex = 0;
- for(size_t i = 0; i < mQueueFamilyProperties.size(); ++i)
- {
-
- // set present family upon surface creation
- if(familyPresent == -1u)
- {
- vk::Bool32 supported{false};
-
- mVkPhysicalDevice.getSurfaceSupportKHR(queueIndex, Surface(retval.GetObject()).GetSurface(), &supported);
- if(supported)
- {
- familyPresent = queueIndex;
- break;
- }
- }
- ++queueIndex;
- }
-
- assert(familyPresent != -1u && "Surface not supported");
-
- return retval;
-}
-
-/**************************************************************************
- * Handle implementation
- */
-
-PhysicalDeviceImpl* GetImpl(const PhysicalDevice* handle)
-{
- return static_cast< PhysicalDeviceImpl* >(handle->GetObject());
-}
-
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wlarger-than="
-GraphicsPhysicalDevice PhysicalDevice::New()
-{
- return GraphicsPhysicalDevice(new PhysicalDeviceImpl());
-}
-#pragma GCC diagnostic pop
-
-vk::Instance PhysicalDevice::GetInstance() const
-{
- return GetImpl(this)->GetInstance();
-}
-
-vk::PhysicalDevice PhysicalDevice::GetPhysicalDevice() const
-{
- return GetImpl(this)->GetPhysicalDevice();
-}
-
-const vk::PhysicalDeviceFeatures& PhysicalDevice::GetFeatures() const
-{
- return GetImpl(this)->GetFeatures();
-}
-
-const vk::PhysicalDeviceProperties& PhysicalDevice::GetProperties() const
-{
- return GetImpl(this)->GetProperties();
-}
-
-const vk::PhysicalDeviceLimits& PhysicalDevice::GetLimits() const
-{
- return GetImpl(this)->GetLimits();
-}
-
-const vk::PhysicalDeviceMemoryProperties& PhysicalDevice::GetMemoryProperties() const
-{
- return GetImpl(this)->GetMemoryProperties();
-}
-
-const std::string& PhysicalDevice::GetName() const
-{
- return GetImpl(this)->GetName();
-}
-
-const std::string& PhysicalDevice::GetVendorName() const
-{
- return GetImpl(this)->GetVendorName();
-}
-
-const vk::AllocationCallbacks* PhysicalDevice::GetAllocator() const
-{
- return GetImpl(this)->GetAllocator();
-}
-
-uint32_t PhysicalDevice::GetQueueFamilyIndex(QueueType type) const
-{
- return GetImpl(this)->GetQueueFamilyIndex(type);
-}
-
-} // Vulkan
-} // Graphics
-} // Dali
\ No newline at end of file
+++ /dev/null
-#ifndef DALI_CORE_GRAPHICS_VULKAN_PHYSICAL_DEVICE_H
-#define DALI_CORE_GRAPHICS_VULKAN_PHYSICAL_DEVICE_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/graphics-physical-device.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-namespace Vulkan
-{
-class PhysicalDevice : public GraphicsPhysicalDevice
-{
-public:
- PhysicalDevice(Integration::GraphicsPhysicalDeviceBase* impl = nullptr)
- : GraphicsPhysicalDevice{impl}
- {
- }
-
- using GraphicsPhysicalDevice::operator=;
-
- // must not be virtual! ( for now )
- static GraphicsPhysicalDevice New();
-
- uint32_t GetQueueFamilyIndex(QueueType type) const;
-
-public:
- // getters of bound Vulkan objects
- vk::Instance GetInstance() const;
- vk::PhysicalDevice GetPhysicalDevice() const;
- const vk::AllocationCallbacks* GetAllocator() const;
- const vk::PhysicalDeviceFeatures& GetFeatures() const;
- const vk::PhysicalDeviceProperties& GetProperties() const;
- const vk::PhysicalDeviceLimits& GetLimits() const;
- const vk::PhysicalDeviceMemoryProperties& GetMemoryProperties() const;
- const std::string& GetName() const;
- const std::string& GetVendorName() const;
-};
-}
-}
-}
-
-#endif //DALI_CORE_GRAPHICS_VULKAN_PHYSICAL_DEVICE_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/surface.h>
-#include <dali/graphics/vulkan/surface/vulkan-surface-base.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-namespace Vulkan
-{
-
-
-uint32_t Surface::GetWidth() const
-{
- return GetObject()->GetWidth();
-}
-
-uint32_t Surface::GetHeight() const
-{
- return GetObject()->GetHeight();
-}
-
-const vk::SurfaceKHR Surface::GetSurface() const
-{
- return static_cast<VulkanSurfaceBase*>(GetObject())->GetVkSurface();
-}
-
-const vk::SurfaceFormatKHR& Surface::GetFormat() const
-{
- return static_cast<VulkanSurfaceBase*>(GetObject())->GetVkSurfaceFormat();
-}
-
-const vk::SurfaceCapabilitiesKHR& Surface::GetCapabilities() const
-{
- return static_cast<VulkanSurfaceBase*>(GetObject())->GetCapabilities();
-}
-
-const std::vector< vk::SurfaceFormatKHR >& Surface::GetAllFormats() const
-{
- return static_cast<VulkanSurfaceBase*>(GetObject())->GetAllFormats();
-}
-
-} // Vulkan
-} // Graphics
-} // Dali
+++ /dev/null
-#ifndef DALI_CORE_GRAPHICS_VULKAN_SURFACE_H
-#define DALI_CORE_GRAPHICS_VULKAN_SURFACE_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/graphics-surface.h>
-#include <dali/graphics/vulkan/common.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-namespace Vulkan
-{
-/**
- * This is a common handle for Vulkan surface implementation
- */
-class Surface : public GraphicsSurface
-{
-public:
- Surface(Integration::GraphicsSurfaceBase* impl = nullptr) : GraphicsSurface{impl}
- {
- }
- using GraphicsSurface::operator=;
-
- /**
- * Returns surface width
- * @return
- */
- uint32_t GetWidth() const;
-
- /**
- * Returns surface height
- * @return
- */
- uint32_t GetHeight() const;
-
- // Vulkan specific API
-public:
- /**
- * Returns associated Vulkan surface object
- * @return
- */
- const vk::SurfaceKHR GetSurface() const;
-
- /**
- * Returns current surface format
- * @return
- */
- const vk::SurfaceFormatKHR& GetFormat() const;
-
- /**
- *
- * @return
- */
- const vk::SurfaceCapabilitiesKHR& GetCapabilities() const;
-
- /**
- *
- * @return
- */
- const std::vector< vk::SurfaceFormatKHR >& GetAllFormats() const;
-};
-
-} // Vulkan
-} // Graphics
-} // Dali
-
-#endif //DALI_CORE_GRAPHICS_VULKAN_SURFACE_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.
- *
- */
-
-#ifndef DALI_CORE_VULKAN_SURFACE_BASE_H
-#define DALI_CORE_VULKAN_SURFACE_BASE_H
-
-#include <dali/graphics/integration/graphics-surface-base.h>
-#include <dali/graphics/vulkan/common.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-class GraphicsPhysicalDevice;
-
-namespace Vulkan
-{
-
-/**
- * Internal interface inherited by the Surface implementation
- */
-class VulkanSurfaceBase : public Integration::GraphicsSurfaceBase
-{
-public:
- VulkanSurfaceBase(const GraphicsPhysicalDevice& physicalDevice)
- : Integration::GraphicsSurfaceBase(physicalDevice){};
- virtual ~VulkanSurfaceBase() = default;
-
- virtual const vk::SurfaceKHR GetVkSurface() const = 0;
- virtual const vk::SurfaceFormatKHR& GetVkSurfaceFormat() const = 0;
- virtual const vk::SurfaceCapabilitiesKHR& GetCapabilities() const = 0;
- virtual const std::vector< vk::SurfaceFormatKHR >& GetAllFormats() const = 0;
-};
-}
-}
-}
-
-#endif //DALI_CORE_VULKAN_SURFACE_BASE_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/physical-device.h>
-#include <dali/graphics/vulkan/surface/xcb-surface.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-namespace Vulkan
-{
-
-XcbSurface::XcbSurface(const GraphicsPhysicalDevice &device, xcb_connection_t *connection, xcb_window_t window)
-: VulkanSurfaceBase(device), mPhysicalDevice(device), mConnection(connection), mWindow(window)
-{
-}
-
-// GraphicsSurfaceBase
-
-bool XcbSurface::Initialise()
-{
- xcb_generic_error_t *err;
-
- PhysicalDevice device(mPhysicalDevice.GetObject());
-
- auto cookie = xcb_get_geometry(mConnection, mWindow);
- auto reply = xcb_get_geometry_reply(mConnection, cookie, &err);
-
- mSurfaceWidth = reply->width;
- mSurfaceHeight = reply->height;
-
- auto vkInstance = device.GetInstance();
- auto vkAllocator = device.GetAllocator();
- vk::XcbSurfaceCreateInfoKHR info;
- info.setConnection(mConnection).setWindow(mWindow);
-
- VkAssertCall(vkInstance.createXcbSurfaceKHR(&info, vkAllocator, &mSurface));
-
- mFormats = device.GetPhysicalDevice().getSurfaceFormatsKHR(mSurface).value;
- mCapabilities = device.GetPhysicalDevice().getSurfaceCapabilitiesKHR(mSurface).value;
- mDefaultFormat = mFormats[0];
- for(auto&& format : mFormats)
- {
- if(format.format == vk::Format::eR8G8B8A8Unorm)
- {
- mDefaultFormat = format;
- }
- }
-
- return true;
-}
-
-bool XcbSurface::Replace()
-{
- assert( true && "XcbSurface::Replace() not implemented!");
- return false;
-}
-
-bool XcbSurface::Destroy()
-{
- assert( true && "XcbSurface::Destroy() not implemented!");
- return false;
-}
-
-uint32_t XcbSurface::GetWidth()
-{
- return mSurfaceWidth;
-}
-
-uint32_t XcbSurface::GetHeight()
-{
- return mSurfaceHeight;
-}
-
-// VulkanSurfaceBase
-
-const vk::SurfaceKHR XcbSurface::GetVkSurface() const
-{
- return mSurface;
-}
-
-const vk::SurfaceFormatKHR& XcbSurface::GetVkSurfaceFormat() const
-{
- return mDefaultFormat;
-}
-
-const vk::SurfaceCapabilitiesKHR& XcbSurface::GetCapabilities() const
-{
- return mCapabilities;
-}
-
-const std::vector< vk::SurfaceFormatKHR >& XcbSurface::GetAllFormats() const
-{
- return mFormats;
-}
-
-
-}
-}
-}
\ No newline at end of file
+++ /dev/null
-#ifndef DALI_CORE_GRAPHICS_VULKAN_XCB_SURFACE_H
-#define DALI_CORE_GRAPHICS_VULKAN_XCB_SURFACE_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/surface/vulkan-surface-base.h>
-#include <xcb/xcb.h>
-#include <cinttypes>
-
-namespace Dali
-{
-namespace Graphics
-{
-class GraphicsPhysicalDevice;
-
-struct XcbSurfaceCreateInfo : NativeSurfaceCreateInfo
-{
- XcbSurfaceCreateInfo() : NativeSurfaceCreateInfo(NativeSurfaceType::XCB)
- {
- }
- xcb_connection_t* connection;
- xcb_window_t window;
-};
-
-namespace Vulkan
-{
-
-/**
- * Implementation of Xcb surface
- */
-class XcbSurface : public VulkanSurfaceBase
-{
-public:
- XcbSurface(const GraphicsPhysicalDevice& adaptor, xcb_connection_t* connection, xcb_window_t window);
-
- virtual ~XcbSurface() = default;
-
- // GraphicsSurfaceBase
-
- virtual bool Initialise();
-
- virtual bool Replace();
-
- virtual bool Destroy();
-
- virtual uint32_t GetWidth();
-
- virtual uint32_t GetHeight();
-
- // VulkanSurfaceBase
-
- virtual const vk::SurfaceKHR GetVkSurface() const;
-
- virtual const vk::SurfaceFormatKHR& GetVkSurfaceFormat() const;
-
- virtual const vk::SurfaceCapabilitiesKHR& GetCapabilities() const;
-
- virtual const std::vector< vk::SurfaceFormatKHR >& GetAllFormats() const;
-
-private:
- GraphicsPhysicalDevice mPhysicalDevice{nullptr};
-
- vk::SurfaceKHR mSurface{nullptr};
- vk::SurfaceCapabilitiesKHR mCapabilities{};
- vk::SurfaceFormatKHR mDefaultFormat{};
- std::vector< vk::SurfaceFormatKHR > mFormats{};
-
- uint32_t mSurfaceWidth{0u};
- uint32_t mSurfaceHeight{0u};
-
- xcb_connection_t* mConnection{nullptr};
- xcb_window_t mWindow{};
-};
-}
-}
-}
-
-#endif //DALI_CORE_GRAPHICS_VULKAN_XCB_SURFACE_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/physical-device.h>
-#include <dali/graphics/vulkan/surface/xlib-surface.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-namespace Vulkan
-{
-
-XlibSurface::XlibSurface(const GraphicsPhysicalDevice &device, Display* display, Window window)
-: VulkanSurfaceBase(device), mPhysicalDevice(device), mDisplay(display), mWindow(window)
-{
-}
-
-// GraphicsSurfaceBase
-
-bool XlibSurface::Initialise()
-{
- PhysicalDevice device(mPhysicalDevice.GetObject());
-
- Window root;
- int x, y;
- unsigned int width, height, borderWidth, depth;
-
- XGetGeometry( mDisplay, mWindow, &root, &x, &y, &width, &height, &borderWidth, &depth );
-
- mSurfaceWidth = width;
- mSurfaceHeight = height;
-
- auto vkInstance = device.GetInstance();
- auto vkAllocator = device.GetAllocator();
- vk::XlibSurfaceCreateInfoKHR info;
- info.setWindow( mWindow );
- info.setDpy( mDisplay );
-
- VkAssertCall(vkInstance.createXlibSurfaceKHR(&info, vkAllocator, &mSurface));
-
- mFormats = device.GetPhysicalDevice().getSurfaceFormatsKHR(mSurface).value;
- mCapabilities = device.GetPhysicalDevice().getSurfaceCapabilitiesKHR(mSurface).value;
- mDefaultFormat = mFormats[0];
- for(auto&& format : mFormats)
- {
- if(format.format == vk::Format::eR8G8B8A8Unorm)
- {
- mDefaultFormat = format;
- }
- }
-
- return true;
-}
-
-bool XlibSurface::Replace()
-{
- assert( "XcbSurface::Replace() not implemented!");
- return false;
-}
-
-bool XlibSurface::Destroy()
-{
- assert( "XcbSurface::Destroy() not implemented!");
- return false;
-}
-
-uint32_t XlibSurface::GetWidth()
-{
- return mSurfaceWidth;
-}
-
-uint32_t XlibSurface::GetHeight()
-{
- return mSurfaceHeight;
-}
-
-// VulkanSurfaceBase
-
-const vk::SurfaceKHR XlibSurface::GetVkSurface() const
-{
- return mSurface;
-}
-
-const vk::SurfaceFormatKHR& XlibSurface::GetVkSurfaceFormat() const
-{
- return mDefaultFormat;
-}
-
-const vk::SurfaceCapabilitiesKHR& XlibSurface::GetCapabilities() const
-{
- return mCapabilities;
-}
-
-const std::vector< vk::SurfaceFormatKHR >& XlibSurface::GetAllFormats() const
-{
- return mFormats;
-}
-
-
-}
-}
-}
\ No newline at end of file
+++ /dev/null
-#ifndef DALI_CORE_GRAPHICS_VULKAN_XLIB_SURFACE_H
-#define DALI_CORE_GRAPHICS_VULKAN_XLIB_SURFACE_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 <X11/Xlib.h>
-#include <dali/graphics/vulkan/surface/vulkan-surface-base.h>
-#include <cinttypes>
-
-namespace Dali
-{
-namespace Graphics
-{
-class GraphicsPhysicalDevice;
-
-struct XlibSurfaceCreateInfo : NativeSurfaceCreateInfo
-{
- XlibSurfaceCreateInfo() : NativeSurfaceCreateInfo(NativeSurfaceType::X11)
- {
- }
- Display* display;
- Window window;
-};
-
-namespace Vulkan
-{
-
-/**
- * Implementation of Xlib surface
- */
-class XlibSurface : public VulkanSurfaceBase
-{
-public:
- XlibSurface(const GraphicsPhysicalDevice& device, Display* display, Window window);
-
- virtual ~XlibSurface() = default;
-
- // GraphicsSurfaceBase
-
- virtual bool Initialise();
-
- virtual bool Replace();
-
- virtual bool Destroy();
-
- virtual uint32_t GetWidth();
-
- virtual uint32_t GetHeight();
-
- // VulkanSurfaceBase
-
- virtual const vk::SurfaceKHR GetVkSurface() const;
-
- virtual const vk::SurfaceFormatKHR& GetVkSurfaceFormat() const;
-
- virtual const vk::SurfaceCapabilitiesKHR& GetCapabilities() const;
-
- virtual const std::vector< vk::SurfaceFormatKHR >& GetAllFormats() const;
-
-private:
- GraphicsPhysicalDevice mPhysicalDevice{nullptr};
-
- vk::SurfaceKHR mSurface{nullptr};
- vk::SurfaceCapabilitiesKHR mCapabilities{};
- vk::SurfaceFormatKHR mDefaultFormat{};
- std::vector< vk::SurfaceFormatKHR > mFormats{};
-
- uint32_t mSurfaceWidth{0u};
- uint32_t mSurfaceHeight{0u};
-
- Display* mDisplay{nullptr};
- Window mWindow{};
-};
-}
-}
-}
-
-#endif //DALI_CORE_GRAPHICS_VULKAN_XLIB_SURFACE_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/command-buffer.h>
-#include <dali/graphics/vulkan/command-pool.h>
-#include <dali/graphics/vulkan/command-queue.h>
-#include <dali/graphics/vulkan/device-memory.h>
-#include <dali/graphics/vulkan/frame-stack.h>
-#include <dali/graphics/vulkan/image.h>
-#include <dali/graphics/vulkan/logical-device.h>
-#include <dali/graphics/vulkan/surface.h>
-#include <dali/graphics/vulkan/swapchain.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-namespace Vulkan
-{
-
-struct SwapchainFramebuffer
-{
- vk::Framebuffer framebuffer{nullptr};
-
- vk::Image image{nullptr};
- vk::ImageView imageView{nullptr};
- vk::ImageLayout layout{vk::ImageLayout::eUndefined};
-
- CommandBuffer commandBuffer;
- bool submitted{false};
- vk::Fence fence{nullptr};
-};
-
-using SwapchainBufferArray = std::vector< SwapchainFramebuffer >;
-
-// swapchain implementation
-class SwapchainImpl : public Integration::GraphicsSwapchainBase
-{
-public:
- SwapchainImpl(const LogicalDevice& device, const Vulkan::Surface& surface, uint32_t bufferCount,
- DepthStencil depthStencil);
- virtual ~SwapchainImpl() = default;
-
- /**
- * Presents frame
- * @param queue
- */
- void Present(const CommandQueue& queue);
-
- /**
- *
- */
- void Present();
-
- /**
- * Begins new frame
- */
- void BeginFrame();
-
- /**
- * Replace swapchain
- */
- void Replace();
-
- /**
- * Creates optional depth/stencil buffer
- */
- void CreateDepthStencil();
-
- /**
- * Obtains swapchain images
- */
- void GetSwapchainImages();
-
- /**
- * Creates main render pass used by swapchain
- */
- void CreateMainRenderPass();
-
- /**
- * Creates main commandbuffers related to the swapchain
- */
- void CreateCommandBuffers();
-
- /**
- * Creates necessary semaphores
- */
- void CreateSemaphores();
-
- /**
- *
- * @param index
- * @return
- */
- const CommandBuffer& GetCommandBuffer(uint32_t index) const
- {
- return mBuffers[index].commandBuffer;
- }
-
- /**
- *
- * @return
- */
- const CommandBuffer& GetCurrentCommandBuffer() const
- {
- return mBuffers[mAcquiredBufferIndex].commandBuffer;
- }
-
- const vk::Image& GetCurrentImage() const
- {
- return mBuffers[mAcquiredBufferIndex].image;
- }
-
- // swapchain integration
-public:
- virtual bool Initialise();
-
- virtual bool AcquireFrame();
-
- virtual bool PresentFrame();
-
-private:
- void GenerateViewFramebuffer(uint32_t bufferIndex, const vk::Image& image);
-
- void BeginRenderPass(CommandBuffer& cmdbuf);
- void RecordDepthStencilBarrier(vk::ImageMemoryBarrier& barrier);
- void RecordColorBarrier(vk::ImageMemoryBarrier& barrier, SwapchainFramebuffer& swapbuffer);
- void AcquireNextImage();
-
- vk::SwapchainKHR mVkSwapchain{nullptr};
- vk::SwapchainKHR mVkOldSwapchain{nullptr};
-
- // Depth/stencil
- Image mVkDepthStencilImage{nullptr};
- vk::ImageView mVkDepthStencilImageView{nullptr};
- DeviceMemory mVkDepthStencilImageMemory{nullptr};
- vk::Format mDepthStencilFormat{};
- bool mDepthStencilLayoutChangeNeeded{false}; // this flag indicates whether with new frame it's also necessary to change image layout (done once only)
-
- // renderpass
- vk::RenderPass mRenderPass{nullptr};
-
- LogicalDevice mDevice;
-
- Surface mSurface;
-
- SwapchainBufferArray mBuffers{};
-
- std::vector< vk::Semaphore > mAcquireSemaphore; // array of semaphores, can't be placed inside the buffer as
- // we don't know the first index
- std::vector< vk::Semaphore > mPresentSemaphore;
-
- CommandPool mCommandPool{nullptr}; // command pool
-
- uint32_t mCurrentBufferIndex{0};
- uint32_t mAcquiredBufferIndex{-1u};
- uint32_t mMaxBufferCount{-1u};
- DepthStencil mDepthStencilMode;
-};
-
-SwapchainImpl::SwapchainImpl(const LogicalDevice& device, const Vulkan::Surface& surface,
- uint32_t bufferCount, DepthStencil depthStencil)
-: GraphicsSwapchainBase(), mDevice(device), mSurface{surface}, mMaxBufferCount(bufferCount), mDepthStencilMode(depthStencil)
-{
-}
-
-bool SwapchainImpl::Initialise()
-{
- // create new command pool for new swapchain
- if(!mCommandPool)
- {
- mCommandPool = mDevice.CreateCommandPool(QueueType::GRAPHICS, false, false);
- }
- // just replace swapchain
- Replace();
- return true;
-}
-
-bool SwapchainImpl::AcquireFrame()
-{
- BeginFrame();
- return true;
-}
-
-bool SwapchainImpl::PresentFrame()
-{
- Present();
- return true;
-}
-
-/**
- * Replacing surface makes sure all device operations completed as new surface will bring a
- * new image resources etc.
- */
-void SwapchainImpl::Replace()
-{
-
- // wait for device to finish
- if(mVkSwapchain)
- {
- // Todo: make sure no other part of implementation is executing on other threads
- // This situation is very rare so vkDeviceWaitIdle() won't hurt performance
- mDevice.GetVkDevice().waitIdle();
-
- mVkOldSwapchain = mVkSwapchain;
- mVkSwapchain = nullptr;
-
- // todo: if size of surface changed the depth may need to be recreated
- // vkDestroyImageView()
- // vkDestroyImage()
- }
-
- vk::SwapchainCreateInfoKHR info;
- info.setSurface(mSurface.GetSurface())
- .setQueueFamilyIndexCount(0)
- .setPQueueFamilyIndices(nullptr)
- .setPreTransform(vk::SurfaceTransformFlagBitsKHR::eIdentity)
- .setPresentMode(vk::PresentModeKHR::eFifo)
- .setOldSwapchain(mVkOldSwapchain)
- .setMinImageCount(mMaxBufferCount)
- .setImageUsage(vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eTransferDst)
- .setImageSharingMode(vk::SharingMode::eExclusive)
- .setImageExtent({mSurface.GetWidth(), mSurface.GetHeight()})
- .setImageFormat(mSurface.GetFormat().format)
- .setImageColorSpace(mSurface.GetFormat().colorSpace)
- .setCompositeAlpha(vk::CompositeAlphaFlagBitsKHR::eOpaque)
- .setImageArrayLayers(1)
- .setClipped(true);
-
- VkAssertCall(mDevice.GetVkDevice().createSwapchainKHR(&info, mDevice.GetVkAllocator(), &mVkSwapchain));
-
- CreateMainRenderPass();
-
- // create depth stencil buffer
- CreateDepthStencil();
-
- // extract images ( no need to delete existing ones except of views )
- GetSwapchainImages();
-
- // Create semaphores ( 2 per buffer );
- CreateSemaphores();
-
- // create command buffers ( won't do anything if buffers are already allocated )
- // fixme: it might not be a good idea to reuse previous buffers
- CreateCommandBuffers();
-
- mCurrentBufferIndex = 0;
-}
-
-void SwapchainImpl::CreateDepthStencil()
-{
- if(mDepthStencilMode == DepthStencil::NONE)
- {
- return;
- }
-
- // free any existing depth buffer
- if(mVkDepthStencilImageView)
- {
- mDevice.GetVkDevice().destroyImageView(mVkDepthStencilImageView, mDevice.GetVkAllocator());
- }
- if(mVkDepthStencilImage)
- {
- //mDevice.GetVkDevice().destroyImage(mVkDepthStencilImage, mDevice.GetVkAllocator());
- mVkDepthStencilImage = nullptr;
- }
-
- // todo: include the proper depth stencil settings
- vk::Format format = vk::Format::eD16Unorm;
- mDepthStencilFormat = format;
-
- Stack stack(1024);
-
- auto& imageInfo = *stack.AllocNew< vk::ImageCreateInfo >();
- auto& imageViewInfo = *stack.AllocNew< vk::ImageViewCreateInfo >();
-
- imageInfo.setPQueueFamilyIndices(nullptr)
- .setQueueFamilyIndexCount(0)
- .setSamples(vk::SampleCountFlagBits::e1)
- .setInitialLayout(vk::ImageLayout::eUndefined)
- .setArrayLayers(1)
- .setExtent({mSurface.GetWidth(), mSurface.GetHeight(), 1})
- .setImageType(vk::ImageType::e2D)
- .setMipLevels(1)
- .setSharingMode(vk::SharingMode::eExclusive)
- .setTiling(vk::ImageTiling::eOptimal)
- .setFormat(format)
- .setUsage(vk::ImageUsageFlagBits::eDepthStencilAttachment);
-
- // create image
- mVkDepthStencilImage = Image::New(mDevice, imageInfo);
-
- imageViewInfo.setFormat(format)
- .setSubresourceRange(vk::ImageSubresourceRange()
- .setLayerCount(1)
- .setBaseArrayLayer(0)
- .setBaseMipLevel(0)
- .setLevelCount(1)
- .setLayerCount(1)
- .setAspectMask(vk::ImageAspectFlagBits::eDepth))
- .setImage(*mVkDepthStencilImage)
- .setViewType(vk::ImageViewType::e2D)
- .setComponents(vk::ComponentMapping()
- .setR(vk::ComponentSwizzle::eR)
- .setG(vk::ComponentSwizzle::eG)
- .setB(vk::ComponentSwizzle::eB)
- .setA(vk::ComponentSwizzle::eA));
-
- // create view
- VkAssertCall(mDevice.GetVkDevice().createImageView(&imageViewInfo, mDevice.GetVkAllocator(),
- &mVkDepthStencilImageView));
-
- // allocate memory
- mVkDepthStencilImageMemory =
- mDevice.AllocateImageMemory(mVkDepthStencilImage, vk::MemoryPropertyFlagBits::eDeviceLocal, false);
- mVkDepthStencilImage.BindDeviceMemory(mVkDepthStencilImageMemory);
-
- // request changing layout with next frame
- mDepthStencilLayoutChangeNeeded = true;
-}
-
-void SwapchainImpl::GetSwapchainImages()
-{
- auto device = mDevice.GetVkDevice();
- if(!mBuffers.empty())
- {
- // delete only views, images are discarded by swapchain as swapchain bound resource
- // we do not discard existing command buffers, no need when replacing swapchain
- for(auto&& buffer : mBuffers)
- {
- device.destroyImageView(buffer.imageView, mDevice.GetVkAllocator());
- device.destroyFramebuffer(buffer.framebuffer, mDevice.GetVkAllocator());
- buffer.imageView = nullptr;
- buffer.framebuffer = nullptr;
- }
- }
-
- // obtain images
- auto images = device.getSwapchainImagesKHR(mVkSwapchain).value;
- assert(images.size() == mMaxBufferCount);
-
- if(mBuffers.empty())
- {
- mBuffers.resize(images.size());
- }
-
- // generate views and framebuffers
- for(uint32_t i = 0; i < mBuffers.size(); ++i)
- {
- GenerateViewFramebuffer(i, images[i]);
- }
-}
-
-void SwapchainImpl::GenerateViewFramebuffer(uint32_t bufferIndex, const vk::Image& image)
-{
- Stack stack(1024);
- auto& ivInfo = *stack.AllocNew< vk::ImageViewCreateInfo >();
- ivInfo.components = (*stack.AllocNew< vk::ComponentMapping >())
- .setR(vk::ComponentSwizzle::eR)
- .setG(vk::ComponentSwizzle::eG)
- .setB(vk::ComponentSwizzle::eB)
- .setA(vk::ComponentSwizzle::eA);
- ivInfo.viewType = vk::ImageViewType::e2D;
- ivInfo.image = image;
- ivInfo.subresourceRange = (*stack.AllocNew< vk::ImageSubresourceRange >())
- .setLayerCount(1)
- .setBaseArrayLayer(0)
- .setBaseMipLevel(0)
- .setLevelCount(1)
- .setLayerCount(1)
- .setAspectMask(vk::ImageAspectFlagBits::eColor);
- ivInfo.setFormat(mSurface.GetFormat().format);
-
- auto& fbInfo = *stack.AllocNew< vk::FramebufferCreateInfo >();
-
- fbInfo.pAttachments = nullptr;
- fbInfo.attachmentCount = mDepthStencilMode != DepthStencil::NONE ? 2 : 1;
- fbInfo.renderPass = mRenderPass;
- fbInfo.layers = 1;
- fbInfo.width = mSurface.GetWidth();
- fbInfo.height = mSurface.GetHeight();
-
- auto& buffer = mBuffers[bufferIndex];
-
- // create image view
- buffer.image = image;
- ivInfo.setImage(buffer.image);
- VkAssertCall(mDevice.GetVkDevice().createImageView(&ivInfo, mDevice.GetVkAllocator(), &buffer.imageView));
-
- auto attachments = stack.Alloc< vk::ImageView >(2);
- attachments[0] = buffer.imageView;
- attachments[1] = mVkDepthStencilImageView;
-
- // create framebuffer
- fbInfo.pAttachments = attachments;
- VkAssertCall(mDevice.GetVkDevice().createFramebuffer(&fbInfo, mDevice.GetVkAllocator(), &buffer.framebuffer));
- buffer.layout = vk::ImageLayout::eUndefined;
-}
-
-void SwapchainImpl::CreateMainRenderPass()
-{
- // Todo: sampling
- // Todo: stencil
- // Todo: separate clear if not needed ( however it's better if render pass does clear framebuffer automatically )
- auto device = mDevice.GetVkDevice();
- auto allocator = mDevice.GetVkAllocator();
-
- auto stack = Stack{1024};
-
- uint32_t attCount = mDepthStencilMode != DepthStencil::NONE ? 2 : 1;
-
- vk::AttachmentReference attRef[2] = {
- vk::AttachmentReference().setLayout(vk::ImageLayout::eColorAttachmentOptimal).setAttachment(0),
- vk::AttachmentReference().setLayout(vk::ImageLayout::eDepthStencilAttachmentOptimal).setAttachment(1)};
-
- auto& subpassDescription = *stack.AllocNew< vk::SubpassDescription >();
- subpassDescription.setPResolveAttachments(nullptr)
- .setPipelineBindPoint(vk::PipelineBindPoint::eGraphics)
- .setPDepthStencilAttachment(attCount == 2 ? &attRef[1] : nullptr)
- .setPColorAttachments(&attRef[0])
- .setColorAttachmentCount(1);
-
- auto attDesc = stack.Alloc< vk::AttachmentDescription >(2);
- attDesc[0] = vk::AttachmentDescription()
- .setFormat(mSurface.GetFormat().format)
- .setInitialLayout(vk::ImageLayout::eColorAttachmentOptimal)
- .setSamples(vk::SampleCountFlagBits::e1)
- .setStoreOp(vk::AttachmentStoreOp::eStore)
- .setStencilLoadOp(vk::AttachmentLoadOp::eClear)
- .setLoadOp(vk::AttachmentLoadOp::eClear)
- .setFinalLayout(vk::ImageLayout::ePresentSrcKHR);
- attDesc[1] = vk::AttachmentDescription()
- .setFormat(mDepthStencilFormat)
- .setInitialLayout(vk::ImageLayout::eDepthStencilAttachmentOptimal)
- .setSamples(vk::SampleCountFlagBits::e1)
- .setStoreOp(vk::AttachmentStoreOp::eDontCare)
- .setStencilLoadOp(vk::AttachmentLoadOp::eClear)
- .setLoadOp(vk::AttachmentLoadOp::eClear)
- .setFinalLayout(vk::ImageLayout::eDepthStencilAttachmentOptimal);
-
- auto& rpInfo = stack.AllocNewRef< vk::RenderPassCreateInfo >();
- rpInfo.setSubpassCount(1).setPSubpasses(&subpassDescription).setAttachmentCount(attCount).setPAttachments(attDesc);
-
- VkAssertCall(device.createRenderPass(&rpInfo, allocator, &mRenderPass));
-}
-
-void SwapchainImpl::CreateCommandBuffers()
-{
- auto device = mDevice.GetVkDevice();
- for(auto&& buffer : mBuffers)
- {
- // create command buffer
- if(!buffer.commandBuffer)
- {
- buffer.commandBuffer = mCommandPool.AllocateCommandBuffer(true);
- }
-
- // create fence
- if(!buffer.fence)
- {
- vk::FenceCreateInfo info;
- VkAssertCall(device.createFence(&info, mDevice.GetVkAllocator(), &buffer.fence));
- }
- }
-}
-
-void SwapchainImpl::CreateSemaphores()
-{
- auto device = mDevice.GetVkDevice();
- if(mAcquireSemaphore.empty())
- {
- mAcquireSemaphore.resize(mMaxBufferCount + 1);
- }
- if(mPresentSemaphore.empty())
- {
- mPresentSemaphore.resize(mMaxBufferCount + 1);
- }
-
- vk::SemaphoreCreateInfo info;
- for(auto&& sem : mAcquireSemaphore)
- {
- if(!sem)
- {
- VkAssertCall(device.createSemaphore(&info, mDevice.GetVkAllocator(), &sem));
- }
- }
- for(auto&& sem : mPresentSemaphore)
- {
- if(!sem)
- {
- VkAssertCall(device.createSemaphore(&info, mDevice.GetVkAllocator(), &sem));
- }
- }
-}
-
-void SwapchainImpl::BeginFrame()
-{
- auto& stack = mDevice.GetStack(0);
- auto frame = stack.Mark();
-
- auto& swapbuffer = mBuffers[mAcquiredBufferIndex];
- auto& cmdbuf = swapbuffer.commandBuffer;
-
- AcquireNextImage();
-
- cmdbuf.Reset();
- cmdbuf.Begin(true);
-
- // change layouts if necessary
- auto barriers = stack.Alloc< vk::ImageMemoryBarrier >(2);
- uint32_t barrierIndex = 0;
- // change depth/stencil attachment layout
- if(mDepthStencilMode != DepthStencil::NONE && mDepthStencilLayoutChangeNeeded)
- {
- RecordDepthStencilBarrier(barriers[barrierIndex++]);
- mDepthStencilLayoutChangeNeeded = false;
- }
-
- // change color attachment layout
- if(swapbuffer.layout != vk::ImageLayout::eColorAttachmentOptimal)
- {
- RecordColorBarrier(barriers[barrierIndex++], swapbuffer);
- }
-
- // record pipeline barrier command
- cmdbuf->pipelineBarrier(vk::PipelineStageFlagBits::eTopOfPipe,
- vk::PipelineStageFlagBits::eTopOfPipe, vk::DependencyFlags(), 0, nullptr,
- 0, nullptr, static_cast< uint32_t >(barrierIndex), &barriers[0]);
-
- BeginRenderPass(cmdbuf);
-
- stack.Rollback(frame);
-}
-
-void SwapchainImpl::AcquireNextImage()
-{
- auto device = mDevice.GetVkDevice();
- auto semaphore = mAcquireSemaphore[mCurrentBufferIndex];
- auto& swapbuffer = mBuffers[mAcquiredBufferIndex];
-
- // acquire new image
- VkTestCall(device.acquireNextImageKHR(mVkSwapchain, 1000000u, semaphore, nullptr, &mAcquiredBufferIndex));
-
- // check fence of selected buffer
- if(swapbuffer.submitted)
- {
- // fixme: ugly busy wait which in most of cases should not happen
-
- while(device.waitForFences(1, &swapbuffer.fence, false, 1000000) != vk::Result::eSuccess)
- {
- }
- }
- VkAssertCall(device.resetFences(1, &swapbuffer.fence));
-}
-
-void SwapchainImpl::RecordDepthStencilBarrier(vk::ImageMemoryBarrier& barrier)
-{
- barrier.setImage(*mVkDepthStencilImage)
- .setSubresourceRange(vk::ImageSubresourceRange()
- .setLayerCount(1)
- .setBaseArrayLayer(0)
- .setBaseMipLevel(0)
- .setLevelCount(1)
- .setLayerCount(1)
- .setAspectMask(vk::ImageAspectFlagBits::eDepth))
- .setSrcAccessMask(vk::AccessFlagBits())
- .setDstAccessMask(vk::AccessFlagBits::eDepthStencilAttachmentWrite)
- .setOldLayout(vk::ImageLayout::eUndefined)
- .setNewLayout(vk::ImageLayout::eDepthStencilAttachmentOptimal);
-}
-
-void SwapchainImpl::RecordColorBarrier(vk::ImageMemoryBarrier& barrier, SwapchainFramebuffer& swapbuffer)
-{
- vk::AccessFlags srcAccess{};
- if(swapbuffer.layout != vk::ImageLayout::eUndefined)
- {
- srcAccess = (vk::AccessFlagBits::eMemoryRead);
- }
-
- barrier.setImage(swapbuffer.image)
- .setSubresourceRange(vk::ImageSubresourceRange()
- .setLayerCount(1)
- .setBaseArrayLayer(0)
- .setBaseMipLevel(0)
- .setLevelCount(1)
- .setLayerCount(1)
- .setAspectMask(vk::ImageAspectFlagBits::eColor))
- .setSrcAccessMask(srcAccess)
- .setDstAccessMask(vk::AccessFlagBits::eColorAttachmentWrite)
- .setOldLayout(swapbuffer.layout)
- .setNewLayout(vk::ImageLayout::eColorAttachmentOptimal);
-
- swapbuffer.layout = vk::ImageLayout::eColorAttachmentOptimal;
-}
-
-void SwapchainImpl::BeginRenderPass(CommandBuffer& cmdbuf)
-{
- auto& stack = mDevice.GetStack(0);
- auto frame = stack.Mark();
-
- auto& swapbuffer = mBuffers[mAcquiredBufferIndex];
- auto& area = stack.AllocNewRef< vk::Rect2D >();
- area.setOffset({0, 0}).setExtent({mSurface.GetWidth(), mSurface.GetHeight()});
-
- // THIS CODE IS VERY TEMPORARY!!!
- static float red = 0.0f;
- red += 0.01f;
- if(red > 1.0f)
- {
- red -= 1.0f;
- }
-
- // clear values
- auto clearValues = stack.Alloc< vk::ClearValue >(2);
-
- // clear color
- clearValues[0] = vk::ClearValue().color.setFloat32({red, 0.0f, 0.0f, 1.0f});
-
- // clear depth/stencil
- clearValues[1] = vk::ClearValue().depthStencil.setDepth(1.0f).setStencil(0);
-
- // begin main render pass
- auto& rpInfo = stack.AllocNewRef< vk::RenderPassBeginInfo >();
- rpInfo.setRenderPass(mRenderPass)
- .setRenderArea(area)
- .setPClearValues(clearValues)
- .setClearValueCount(mDepthStencilMode != DepthStencil::NONE ? 2 : 1)
- .setFramebuffer(swapbuffer.framebuffer);
-
- // begin render pass
- cmdbuf->beginRenderPass(&rpInfo, vk::SubpassContents::eInline);
-
- stack.Rollback(frame);
-}
-
-void SwapchainImpl::Present()
-{
- Present(mDevice.GetCommandQueue(0, QueueType::PRESENT));
-}
-
-void SwapchainImpl::Present(const CommandQueue& queue)
-{
- auto& swapbuffer = mBuffers[mAcquiredBufferIndex];
- auto& cmdbuf = swapbuffer.commandBuffer;
-
- cmdbuf->endRenderPass();
- cmdbuf.End();
-
- vk::PipelineStageFlags waitFlags = vk::PipelineStageFlagBits::eColorAttachmentOutput;
-
- // submit command buffer
- queue.Submit(&cmdbuf, 1, &mAcquireSemaphore[mCurrentBufferIndex], 1, // wait for acquire sem
- &mPresentSemaphore[mCurrentBufferIndex], 1, // signal present sem
- &waitFlags, swapbuffer.fence);
-
- // present
- vk::PresentInfoKHR presentInfo;
- presentInfo.setPImageIndices(&mAcquiredBufferIndex)
- .setPResults(nullptr)
- .setPSwapchains(&mVkSwapchain)
- .setSwapchainCount(1)
- .setWaitSemaphoreCount(1)
- .setPWaitSemaphores(&mPresentSemaphore[mCurrentBufferIndex]);
-
- VkAssertCall(queue.GetVkQueue().presentKHR(&presentInfo));
-
- // set swap buffer image layout manually ( will be changed with end of the render pass automatically )
- swapbuffer.layout = vk::ImageLayout::ePresentSrcKHR;
- swapbuffer.submitted = true;
-
- // increase "logical" buffer
- mCurrentBufferIndex = (mCurrentBufferIndex + 1) % (mMaxBufferCount + 1);
-}
-
-namespace
-{
-SwapchainImpl* GetImpl(const Swapchain* handle)
-{
- return static_cast< SwapchainImpl* >(handle->GetObject());
-}
-}
-
-Swapchain Swapchain::New(const LogicalDevice& context, const Vulkan::Surface& surface,
- uint32_t bufferCount, DepthStencil depthStencil)
-{
- return Swapchain(new SwapchainImpl(context, surface, bufferCount, depthStencil));
-}
-
-const CommandBuffer& Swapchain::GetCommandBuffer(uint32_t index) const
-{
- return GetImpl(this)->GetCommandBuffer(index);
-}
-
-const CommandBuffer& Swapchain::GetCurrentCommandBuffer() const
-{
- return GetImpl(this)->GetCurrentCommandBuffer();
-}
-
-const vk::Image& Swapchain::GetCurrentImage() const
-{
- return GetImpl(this)->GetCurrentImage();
-}
-
-} // Vulkan
-} // Graphics
-} // Dali
+++ /dev/null
-#ifndef DALI_CORE_GRAPHICS_VULKAN_SWAPCHAIN_H
-#define DALI_CORE_GRAPHICS_VULKAN_SWAPCHAIN_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/graphics-swapchain.h>
-#include <dali/graphics/vulkan/common.h>
-
-namespace Dali
-{
-namespace Graphics
-{
-namespace Vulkan
-{
-
-class Surface;
-class LogicalDevice;
-class CommandBuffer;
-
-/**
- * In computer graphics swap chain represents a series of images which are sort of
- * virtual framebuffers.
- * Swapchain class manages mentioned images ( swaps them when needed for example on vsync )
- * and delivers an image to the graphics API as a render target bound to
- * the surface ( simplifying, delivers main framebuffer to render to ).
- */
-class Swapchain : public GraphicsSwapchain
-{
-public:
- Swapchain(Integration::GraphicsSwapchainBase* impl = nullptr) : GraphicsSwapchain{impl}
- {
- }
-
- using GraphicsSwapchain::operator=;
-
- static Swapchain New(const LogicalDevice& device, const Surface& surface, uint32_t bufferCount,
- DepthStencil depthStencil);
-
- const CommandBuffer& GetCommandBuffer(uint32_t index) const;
-
- const CommandBuffer& GetCurrentCommandBuffer() const;
-
- const vk::Image& GetCurrentImage() const;
-};
-
-} // Vulkan
-} // Graphics
-} // Dali
-
-#endif //DALI_CORE_GRAPHICS_VULKAN_SWAPCHAIN_H
--- /dev/null
+//
+// Created by adam.b on 06/06/17.
+//
+
+#include "vulkan-buffer.h"
--- /dev/null
+//
+// Created by adam.b on 06/06/17.
+//
+
+#ifndef VULKAN_PROJECT_BUFFER_H
+#define VULKAN_PROJECT_BUFFER_H
+
+#include <dali/graphics/vulkan/vulkan-types.h>
+
+namespace Dali
+{
+namespace Graphics
+{
+namespace Vulkan
+{
+
+class Buffer
+{
+
+};
+
+}
+}
+}
+
+#endif //VULKAN_PROJECT_BUFFER_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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/graphics/vulkan/vulkan-command-buffer.h>
+#include <dali/graphics/vulkan/vulkan-command-pool.h>
+#include <dali/graphics/vulkan/vulkan-graphics.h>
+
+namespace Dali
+{
+namespace Graphics
+{
+namespace Vulkan
+{
+
+CommandBuffer::CommandBuffer(Graphics& graphics, CommandPool& ownerPool)
+: CommandBuffer(graphics, ownerPool,
+ vk::CommandBufferAllocateInfo().setCommandBufferCount(1).setLevel(vk::CommandBufferLevel::ePrimary))
+{
+}
+
+CommandBuffer::CommandBuffer(Graphics& graphics, CommandPool& ownerPool,
+ const vk::CommandBufferAllocateInfo& allocateInfo)
+: mGraphics(graphics), mCommandPool(ownerPool), mRecording(false)
+{
+ assert(allocateInfo.commandBufferCount == 1 && "Number of buffers to allocate must be equal 1!");
+ mCommandBuffer = VkAssert(mGraphics.GetDevice().allocateCommandBuffers(allocateInfo))[0];
+}
+
+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;
+}
+
+/** Finish recording */
+void CommandBuffer::End()
+{
+ assert(mRecording && "CommandBuffer is not in the recording state!");
+ VkAssert(mCommandBuffer.end());
+ mRecording = false;
+}
+
+/** 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);
+}
+
+/** Free command buffer */
+void CommandBuffer::Free()
+{
+ assert(mCommandBuffer && "Invalid command buffer!");
+ mGraphics.GetDevice().freeCommandBuffers(mCommandPool.GetPool(), mCommandBuffer);
+}
+
+/** Records image layout transition barrier for one image */
+void CommandBuffer::ImageLayoutTransition(vk::Image image,
+ vk::ImageLayout oldLayout,
+ 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;
+ }
+ 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:
+ default:
+ {
+ }
+ }
+
+ 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:
+ default:
+ {
+ }
+ }
+
+ RecordImageLayoutTransition(image, srcAccessMask, dstAccessMask, srcStageMask, dstStageMask,
+ 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);
+}
+#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;
+}
+
+/** Push signal semaphores */
+void CommandBuffer::PushSignalSemaphores(const std::vector< vk::Semaphore >& semaphores)
+{
+ mSignalSemaphores = semaphores;
+}
+
+} // namespace Vulkan
+} // namespace Graphics
+} // namespace Dali
--- /dev/null
+#ifndef DALI_GRAPHICS_VULKAN_COMMAND_BUFFER_H
+#define DALI_GRAPHICS_VULKAN_COMMAND_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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/graphics/vulkan/vulkan-types.h>
+
+namespace Dali
+{
+namespace Graphics
+{
+namespace Vulkan
+{
+
+class Graphics;
+class CommandPool;
+class CommandBuffer
+{
+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();
+
+ /** Begin recording */
+ void Begin(vk::CommandBufferUsageFlags usageFlags = vk::CommandBufferUsageFlags{},
+ vk::CommandBufferInheritanceInfo* inheritanceInfo = nullptr);
+
+ /** Finish recording */
+ void End();
+
+ /** Reset command buffer */
+ void Reset();
+
+ /** Free command buffer */
+ void Free();
+
+ /** Records image layout transition barrier for one image */
+ void ImageLayoutTransition(vk::Image image, vk::ImageLayout oldLayout, vk::ImageLayout newLayout, vk::ImageAspectFlags aspectMask);
+
+ /** Push wait semaphores */
+ void PushWaitSemaphores(const std::vector< vk::Semaphore >& semaphores,
+ const std::vector< vk::PipelineStageFlags >& stages);
+
+ /** Push signal semaphores */
+ void PushSignalSemaphores(const std::vector< vk::Semaphore >& semaphores);
+
+ const std::vector< vk::Semaphore >& GetSignalSemaphores() const
+ {
+ return mSignalSemaphores;
+ }
+
+ const std::vector< vk::Semaphore >& GetSWaitSemaphores() const
+ {
+ return mWaitSemaphores;
+ }
+
+ const std::vector< vk::PipelineStageFlags >& GetWaitSemaphoreStages() const
+ {
+ return mWaitStages;
+ }
+
+ /** Returns Vulkan object associated with the buffer */
+ inline const vk::CommandBuffer& Get() const
+ {
+ return mCommandBuffer;
+ }
+
+private:
+ 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);
+
+private:
+ Graphics& mGraphics;
+
+ CommandPool& mCommandPool;
+
+ // semaphores per command buffer
+ std::vector< vk::Semaphore > mSignalSemaphores;
+ std::vector< vk::Semaphore > mWaitSemaphores;
+ std::vector< vk::PipelineStageFlags > mWaitStages;
+
+ vk::CommandBuffer mCommandBuffer;
+
+ bool mRecording;
+};
+
+} // namespace Vulkan
+} // namespace Graphics
+} // namespace Dali
+
+#endif // DALI_GRAPHICS_VULKAN_COMMAND_BUFFER_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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#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 Graphics
+{
+namespace Vulkan
+{
+
+CommandPool::CommandPool(Graphics& graphics, const vk::CommandPoolCreateInfo& createInfo)
+: mGraphics(graphics)
+{
+ mPool = VkAssert(graphics.GetDevice().createCommandPool(createInfo, graphics.GetAllocator()));
+}
+
+CommandPool::~CommandPool()
+{
+ if(mPool)
+ {
+ mGraphics.GetDevice().destroyCommandPool(mPool, mGraphics.GetAllocator());
+ }
+}
+
+std::unique_ptr< CommandBuffer > CommandPool::AllocateCommandBuffer(
+ const vk::CommandBufferAllocateInfo& info)
+{
+ auto copyInfo = info;
+ copyInfo.setCommandPool(mPool);
+ return MakeUnique<CommandBuffer>(mGraphics, *this, copyInfo);
+}
+
+std::unique_ptr< CommandBuffer > CommandPool::AllocateCommandBuffer(vk::CommandBufferLevel level)
+{
+ auto info =
+ vk::CommandBufferAllocateInfo{}.setCommandBufferCount(1).setLevel(level).setCommandPool(
+ mPool);
+ return MakeUnique<CommandBuffer>(mGraphics, *this, info);
+}
+
+vk::CommandPool CommandPool::GetPool() const
+{
+ return mPool;
+}
+
+} // namespace Vulkan
+} // namespace Graphics
+} // namespace Dali
+
-#ifndef DALI_CORE_GRAPHICS_VULKAN_BUFFER_H
-#define DALI_CORE_GRAPHICS_VULKAN_BUFFER_H
+#ifndef DALI_GRAPHICS_VULKAN_COMMANDPOOL_H
+#define DALI_GRAPHICS_VULKAN_COMMANDPOOL_H
/*
* Copyright (c) 2017 Samsung Electronics Co., Ltd.
*
*/
-#include <dali/graphics/vulkan/common.h>
+// INTERNAL INCLUDES
+#include <dali/graphics/vulkan/vulkan-types.h>
namespace Dali
{
namespace Vulkan
{
-class Buffer : public VkHandle
+class Graphics;
+class CommandBuffer;
+class CommandPool
{
public:
- Buffer(VkObject* impl = nullptr) : VkHandle(impl){}
- using VkHandle::operator=;
- static Buffer New( const class LogicalDevice& device, const vk::BufferCreateInfo& info );
+ CommandPool( Graphics& graphics, const vk::CommandPoolCreateInfo& createInfo );
+ ~CommandPool();
- const vk::Buffer& GetVkResource() const;
- const vk::Buffer& operator*() const;
-
- bool BindDeviceMemory( const class DeviceMemory& memory );
-
- bool BindDeviceMemory( const class DeviceMemory& memory, size_t offset );
+ std::unique_ptr<CommandBuffer> AllocateCommandBuffer( const vk::CommandBufferAllocateInfo& info );
+ std::unique_ptr<CommandBuffer> AllocateCommandBuffer( vk::CommandBufferLevel level );
+ vk::CommandPool GetPool() const;
+private:
+ Graphics& mGraphics;
+ vk::CommandPool mPool;
};
} // namespace Vulkan
-
} // namespace Graphics
-
} // namespace Dali
-#endif // DALI_CORE_GRAPHICS_VULKAN_BUFFER_H
+#endif // DALI_GRAPHICS_VULKAN_COMMANDPOOL_H
--- /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
--- /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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/graphics/vulkan/vulkan-fence.h>
+#include <dali/graphics/vulkan/vulkan-graphics.h>
+
+namespace Dali
+{
+namespace Graphics
+{
+namespace Vulkan
+{
+
+Fence::Fence(Graphics& graphics) : mGraphics(graphics), mFence(nullptr)
+{
+ mFence =
+ VkAssert(mGraphics.GetDevice().createFence(vk::FenceCreateInfo{}, mGraphics.GetAllocator()));
+}
+
+Fence::~Fence()
+{
+ if(mFence)
+ {
+ mGraphics.GetDevice().destroyFence(mFence, mGraphics.GetAllocator());
+ }
+}
+
+bool Fence::Wait(uint32_t timeout)
+{
+ 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;
+ }
+}
+
+void Fence::Reset()
+{
+ if(mFence)
+ {
+ mGraphics.GetDevice().resetFences(mFence);
+ }
+}
+
+vk::Fence Fence::GetFence() const
+{
+ return mFence;
+}
+
+} // namespace Vulkan
+} // namespace Graphics
+} // namespace Dali
-#ifndef DALI_CORE_GRAPHICS_VULKAN_FRAMEBUFFER_H
-#define DALI_CORE_GRAPHICS_VULKAN_FRAMEBUFFER_H
+#ifndef DALI_GRAPHICS_VULKAN_FENCE_H
+#define DALI_GRAPHICS_VULKAN_FENCE_H
/*
* Copyright (c) 2017 Samsung Electronics Co., Ltd.
*
*/
-#include <dali/graphics/vulkan/common.h>
+// INTERNAL INCLUDES
+#include <dali/graphics/vulkan/vulkan-types.h>
namespace Dali
{
namespace Vulkan
{
-class Framebuffer : public VkHandle
+class Graphics;
+class Fence final
{
public:
- OBJECT_HANDLE(Framebuffer)
- const vk::Framebuffer& operator*() const;
+ Fence( Graphics& graphics );
+ Fence( Fence&& ) = default;
+ ~Fence();
- static Framebuffer New( const class LogicalDevice& device, const vk::FramebufferCreateInfo& info );
+ bool Wait( uint32_t timeout = 0u );
+ void Reset();
-};
+ vk::Fence GetFence() const;
-}
-}
-}
+private:
+ Graphics& mGraphics;
+ vk::Fence mFence;
+};
+} // namespace Vulkan
+} // namespace Graphics
+} // namespace Dali
-#endif //DALI_CORE_FRAMEBUFFER_H
+#endif // DALI_GRAPHICS_VULKAN_FENCE_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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/graphics/vulkan/vulkan-graphics.h>
+#include <dali/graphics/vulkan/vulkan-command-pool.h>
+#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>
+
+#ifndef VK_KHR_XLIB_SURFACE_EXTENSION_NAME
+#define VK_KHR_XLIB_SURFACE_EXTENSION_NAME "VK_KHR_xlib_surface"
+#endif
+
+#ifndef VK_KHR_XCB_SURFACE_EXTENSION_NAME
+#define VK_KHR_XCB_SURFACE_EXTENSION_NAME "VK_KHR_xcb_surface"
+#endif
+
+namespace Dali
+{
+namespace Graphics
+{
+using VkSurfaceFactory = Dali::Integration::Graphics::Vulkan::VkSurfaceFactory;
+namespace Vulkan
+{
+
+Graphics::Graphics() = default;
+
+Graphics::~Graphics() = default;
+
+void Graphics::Create()
+{
+ CreateInstance();
+ PreparePhysicalDevice();
+}
+
+void Graphics::CreateInstance()
+{
+ 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())
+ .setEnabledLayerCount(U32(validationLayers.size()))
+ .setPpEnabledLayerNames(validationLayers.data());
+
+ mInstance = VkAssert(vk::createInstance(info, mAllocator));
+}
+
+void Graphics::DestroyInstance()
+{
+ if(mInstance)
+ {
+ mInstance.destroy(mAllocator);
+ mInstance = nullptr;
+ }
+}
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wframe-larger-than="
+void Graphics::PreparePhysicalDevice()
+{
+ auto devices = VkAssert(mInstance.enumeratePhysicalDevices());
+ assert(devices.size() > 0 && "No Vulkan supported device found!");
+
+ // if only one, pick first
+ mPhysicalDevice = nullptr;
+ if(devices.size() == 1)
+ {
+ mPhysicalDevice = devices[0];
+ }
+ else // otherwise look for one which is a graphics device
+ {
+ for(auto& device : devices)
+ {
+ auto properties =device.getProperties();
+ if(properties.deviceType == vk::PhysicalDeviceType::eDiscreteGpu ||
+ properties.deviceType == vk::PhysicalDeviceType::eIntegratedGpu)
+ {
+ mPhysicalDevice = device;
+ break;
+ }
+ }
+ }
+
+ assert(mPhysicalDevice && "No suitable Physical Device found!");
+
+ GetPhysicalDeviceProperties();
+
+ GetQueueFamilyProperties();
+
+ mDeviceMemoryManager = MakeUnique<DeviceMemoryManager>( *this );
+}
+#pragma GCC diagnostic pop
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wframe-larger-than="
+void Graphics::GetPhysicalDeviceProperties()
+{
+ // store data on heap to keep object smaller
+ mPhysicalDeviceProperties =
+ MakeUnique<vk::PhysicalDeviceProperties>(mPhysicalDevice.getProperties());
+ mPhysicalDeviceMemoryProperties =
+ MakeUnique<vk::PhysicalDeviceMemoryProperties>(mPhysicalDevice.getMemoryProperties());
+ mPhysicalDeviceFeatures =
+ MakeUnique<vk::PhysicalDeviceFeatures>(mPhysicalDevice.getFeatures());
+}
+#pragma GCC diagnostic pop
+
+void Graphics::GetQueueFamilyProperties()
+{
+ mQueueFamilyProperties = std::move(mPhysicalDevice.getQueueFamilyProperties());
+}
+
+FBID Graphics::CreateSurface(std::unique_ptr< SurfaceFactory > surfaceFactory)
+{
+ const auto vkFactory = dynamic_cast< const VkSurfaceFactory* >(surfaceFactory.get());
+ if(!vkFactory)
+ {
+ return FBID{0u};
+ }
+
+ auto surface = vkFactory->Create(mInstance, mAllocator, mPhysicalDevice);
+
+ // map surface to FBID
+ auto fbid = ++mBaseFBID;
+ mSurfaceFBIDMap[fbid] = MakeUnique<Surface>(*this, surface, 3u);
+ return fbid;
+}
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wframe-larger-than="
+std::vector< vk::DeviceQueueCreateInfo > Graphics::GetQueueCreateInfos()
+{
+ // surface is needed in order to find a family that supports presentation to this surface
+ // fixme: assuming all surfaces will be compatible with the queue family
+ assert(!mSurfaceFBIDMap.empty() &&
+ "At least one surface has to be created before creating VkDevice!");
+
+ auto queueInfos = std::vector< vk::DeviceQueueCreateInfo >{};
+
+ constexpr uint8_t MAX_QUEUE_TYPES = 3;
+ // find suitable family for each type of queue
+ uint32_t familyIndexType[MAX_QUEUE_TYPES];
+ std::fill(&familyIndexType[0], &familyIndexType[MAX_QUEUE_TYPES], -1u);
+
+ // Graphics
+ auto& graphicsFamily = familyIndexType[0];
+
+ // Transfer
+ auto& transferFamily = familyIndexType[1];
+
+ // Transfer
+ auto& presentFamily = familyIndexType[2];
+
+ auto queueFamilyIndex = 0u;
+ for(auto& prop : mQueueFamilyProperties)
+ {
+ if((prop.queueFlags & vk::QueueFlagBits::eGraphics) && graphicsFamily == -1u)
+ {
+ graphicsFamily = queueFamilyIndex;
+ }
+ if((prop.queueFlags & vk::QueueFlagBits::eTransfer) && transferFamily == -1u)
+ {
+ transferFamily = queueFamilyIndex;
+ }
+ if(mPhysicalDevice.getSurfaceSupportKHR(queueFamilyIndex, mSurfaceFBIDMap.begin()->second.get()->GetSurfaceKHR())
+ .value &&
+ presentFamily == -1u)
+ {
+ presentFamily = queueFamilyIndex;
+ }
+ ++queueFamilyIndex;
+ }
+
+ assert(graphicsFamily != -1u && "No queue family that supports graphics operations!");
+ assert(transferFamily != -1u && "No queue family that supports transfer operations!");
+ assert(presentFamily != -1u && "No queue family that supports present operations!");
+
+ // todo: we may require that the family must be same for all types of operations, it makes
+ // easier to handle synchronisation related issues.
+
+ // sort queues
+ std::sort(&familyIndexType[0], &familyIndexType[MAX_QUEUE_TYPES]);
+
+ // allocate all queues from graphics family
+ uint32_t prevQueueFamilyIndex = -1u;
+
+ for(auto i = 0u; i < MAX_QUEUE_TYPES; ++i)
+ {
+ auto& familyIndex = familyIndexType[i];
+ if(prevQueueFamilyIndex == familyIndex)
+ {
+ continue;
+ }
+
+ auto& queueCount = mQueueFamilyProperties[familyIndex].queueCount;
+
+ // fill queue create info for the family.
+ // note the priorities are not being set as local pointer will out of scope, this
+ // will be fixed by the caller function
+ auto info = vk::DeviceQueueCreateInfo{}
+ .setPQueuePriorities(nullptr)
+ .setQueueCount(queueCount)
+ .setQueueFamilyIndex(familyIndex);
+ queueInfos.push_back(info);
+ prevQueueFamilyIndex = familyIndex;
+ }
+
+ return queueInfos;
+}
+#pragma GCC diagnostic pop
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wframe-larger-than="
+void Graphics::CreateDevice()
+{
+ auto queueInfos = GetQueueCreateInfos();
+ {
+ auto maxQueueCountPerFamily = 0u;
+ for( auto&& info : queueInfos )
+ {
+ maxQueueCountPerFamily = std::max( info.queueCount, maxQueueCountPerFamily );
+ }
+
+ auto priorities = std::vector<float>( maxQueueCountPerFamily );
+ std::fill( priorities.begin(), priorities.end(), 1.0f );
+
+ for( auto& info : queueInfos )
+ {
+ info.setPQueuePriorities( priorities.data() );
+ }
+
+ auto extensions = std::vector< const char* >{VK_KHR_SWAPCHAIN_EXTENSION_NAME};
+
+ auto info = vk::DeviceCreateInfo{};
+ info.setEnabledExtensionCount(U32(extensions.size()))
+ .setPpEnabledExtensionNames(extensions.data())
+ .setPEnabledFeatures(&(*mPhysicalDeviceFeatures))
+ .setPQueueCreateInfos(queueInfos.data())
+ .setQueueCreateInfoCount(U32(queueInfos.size()));
+
+ mDevice = VkAssert(mPhysicalDevice.createDevice(info, mAllocator));
+ }
+
+ // create Queue objects
+ for(auto& queueInfo : queueInfos)
+ {
+ for(auto i = 0u; i < queueInfo.queueCount; ++i)
+ {
+ auto queue = mDevice.getQueue(queueInfo.queueFamilyIndex, i);
+
+ // based on family push queue instance into right array
+ auto flags = mQueueFamilyProperties[queueInfo.queueFamilyIndex].queueFlags;
+ if(flags & vk::QueueFlagBits::eGraphics)
+ {
+ mGraphicsQueues.emplace_back(
+ MakeUnique<Queue>(*this, queue, queueInfo.queueFamilyIndex, i, flags));
+ }
+ if(flags & vk::QueueFlagBits::eTransfer)
+ {
+ mTransferQueues.emplace_back(
+ MakeUnique<Queue>(*this, queue, queueInfo.queueFamilyIndex, i, flags));
+ }
+ if(flags & vk::QueueFlagBits::eCompute)
+ {
+ mComputeQueues.emplace_back(
+ MakeUnique<Queue>(*this, queue, queueInfo.queueFamilyIndex, i, flags));
+ }
+
+ // todo: present queue
+ }
+ }
+}
+#pragma GCC diagnostic pop
+
+vk::Device Graphics::GetDevice() const
+{
+ return mDevice;
+}
+
+vk::PhysicalDevice Graphics::GetPhysicalDevice() const
+{
+ return mPhysicalDevice;
+}
+
+vk::Instance Graphics::GetInstance() const
+{
+ return mInstance;
+}
+
+vk::AllocationCallbacks* Graphics::GetAllocator() const
+{
+ return mAllocator;
+}
+
+Queue& Graphics::GetGraphicsQueue(uint32_t index) const
+{
+ // todo: at the moment each type of queue may use only one, indices greater than 0 are invalid
+ // this will change in the future
+ assert(index == 0u && "Each type of queue may use only one, indices greater than 0 are invalid!");
+
+ return *mGraphicsQueues[0].get(); // will be mGraphicsQueues[index]
+}
+
+Queue& Graphics::GetTransferQueue(uint32_t index) const
+{
+ // todo: at the moment each type of queue may use only one, indices greater than 0 are invalid
+ // this will change in the future
+ assert(index == 0u && "Each type of queue may use only one, indices greater than 0 are invalid!");
+
+ return *mTransferQueues[0].get(); // will be mGraphicsQueues[index]
+}
+
+Queue& Graphics::GetComputeQueue(uint32_t index) const
+{
+ // todo: at the moment each type of queue may use only one, indices greater than 0 are invalid
+ // this will change in the future
+ assert(index == 0u && "Each type of queue may use only one, indices greater than 0 are invalid!");
+
+ return *mComputeQueues[0].get(); // will be mGraphicsQueues[index]
+}
+
+Queue& Graphics::GetPresentQueue() const
+{
+ return *mPresentQueue.get();
+}
+
+std::unique_ptr< CommandPool > Graphics::CreateCommandPool(const vk::CommandPoolCreateInfo& info)
+{
+ auto cmdpool = std::unique_ptr< CommandPool >(new CommandPool(*this, info));
+ return cmdpool;
+}
+
+Surface& Graphics::GetSurface( FBID surfaceId )
+{
+ return *mSurfaceFBIDMap[surfaceId].get();
+}
+
+} // namespace Vulkan
+} // namespace Graphics
+} // namespace Dali
--- /dev/null
+#ifndef DALI_GRAPHICS_VULKAN_GRAPHICS_H
+#define DALI_GRAPHICS_VULKAN_GRAPHICS_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.
+ *
+ */
+
+#ifndef VULKAN_HPP_NO_EXCEPTIONS
+#define VULKAN_HPP_NO_EXCEPTIONS
+#endif
+
+// INTERNAL INCLUDES
+#include <dali/graphics/vulkan/vulkan-types.h>
+#include <dali/integration-api/graphics/surface-factory.h>
+
+namespace Dali
+{
+namespace Graphics
+{
+using SurfaceFactory = Dali::Integration::Graphics::SurfaceFactory;
+
+namespace Vulkan
+{
+
+class Surface;
+class CommandPool;
+class DeviceMemoryManager;
+class Graphics
+{
+
+public:
+ Graphics();
+ Graphics(std::unique_ptr< SurfaceFactory > surfaceFactory);
+ Graphics(const Graphics&) = delete;
+ Graphics& operator=(const Graphics&) = delete;
+ ~Graphics();
+
+ void Create();
+
+ // new way
+ FBID CreateSurface(std::unique_ptr< SurfaceFactory > surfaceFactory);
+
+ Surface& GetSurface( FBID surfaceId );
+
+ void CreateDevice();
+
+ /** Creates new command pool */
+ std::unique_ptr< CommandPool > CreateCommandPool(const vk::CommandPoolCreateInfo& info);
+
+ vk::Device GetDevice() const;
+
+ vk::PhysicalDevice GetPhysicalDevice() const;
+
+ vk::Instance GetInstance() const;
+
+ vk::AllocationCallbacks* GetAllocator() const;
+
+ DeviceMemoryManager& GetDeviceMemoryManager() const
+ {
+ return *mDeviceMemoryManager;
+ }
+
+ const vk::PhysicalDeviceMemoryProperties& GetMemoryProperties() const
+ {
+ return *mPhysicalDeviceMemoryProperties;
+ }
+
+ Queue& GetGraphicsQueue(uint32_t index = 0u) const;
+ Queue& GetTransferQueue(uint32_t index = 0u) const;
+ Queue& GetComputeQueue(uint32_t index = 0u) const;
+ Queue& GetPresentQueue() const;
+
+private:
+
+ void CreateInstance();
+ void DestroyInstance();
+ void PreparePhysicalDevice();
+ void GetPhysicalDeviceProperties();
+ void GetQueueFamilyProperties();
+ std::vector< vk::DeviceQueueCreateInfo > GetQueueCreateInfos();
+
+private:
+
+ std::unique_ptr<DeviceMemoryManager> mDeviceMemoryManager;
+
+ vk::Instance mInstance;
+ vk::AllocationCallbacks* mAllocator{nullptr};
+
+ // physical device
+ vk::PhysicalDevice mPhysicalDevice;
+
+ // logical device
+ vk::Device mDevice;
+
+ // physical device properites
+ std::unique_ptr< vk::PhysicalDeviceProperties > mPhysicalDeviceProperties;
+ std::unique_ptr< vk::PhysicalDeviceMemoryProperties > mPhysicalDeviceMemoryProperties;
+ std::unique_ptr< vk::PhysicalDeviceFeatures > mPhysicalDeviceFeatures;
+
+ // queue family properties
+ std::vector< vk::QueueFamilyProperties > mQueueFamilyProperties;
+
+ std::unordered_map< FBID, UniqueSurface > mSurfaceFBIDMap;
+ FBID mBaseFBID{0u};
+
+ // Sets of queues
+ std::vector< std::unique_ptr<Queue> > mGraphicsQueues;
+ std::vector< std::unique_ptr<Queue> > mTransferQueues;
+ std::vector< std::unique_ptr<Queue> > mComputeQueues;
+ std::unique_ptr< Queue > mPresentQueue;
+};
+
+} // namespace Vulkan
+} // namespace Graphics
+} // namespace Dali
+
+#endif // DALI_GRAPHICS_VULKAN_GRAPHICS_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/vulkan-graphics.h>
+#include <dali/graphics/vulkan/vulkan-image.h>
+
+namespace Dali
+{
+namespace Graphics
+{
+namespace Vulkan
+{
+
+Image::Image(Graphics& graphics, const vk::ImageCreateInfo& createInfo) : mGraphics(graphics)
+{
+}
+
+Image::Image(Graphics& graphics, vk::Image externalImage)
+: mGraphics(graphics), mImage(externalImage)
+{
+}
+
+vk::ImageView Image::CreateUnmanagedView(const vk::ImageViewCreateInfo& info)
+{
+ NotImplemented();
+ return nullptr;
+}
+
+UniqueImageView Image::CreateView(const vk::ImageViewCreateInfo& info)
+{
+ return MakeUnique< ImageView >(mGraphics, *this, info);
+}
+
+ImageView::ImageView(Graphics& graphics, Image& image) : mGraphics(graphics), mImageRef(image)
+{
+}
+
+ImageView::ImageView(Graphics& graphics, Image& image, const VkImageViewCreateInfo& createInfo)
+: mGraphics(graphics), mImageRef(image)
+{
+ mImageView =
+ VkAssert(mGraphics.GetDevice().createImageView(createInfo, mGraphics.GetAllocator()));
+}
+
+ImageView::~ImageView()
+{
+ if(mImageView)
+ {
+ mGraphics.GetDevice().destroyImageView( mImageView, mGraphics.GetAllocator());
+ }
+}
+
+} // namespace Vulkan
+
+} // namespace Graphics
+
+} // namespace Dali
\ No newline at end of file
--- /dev/null
+#ifndef DALI_GRAPHICS_VULKAN_IMAGE_H
+#define DALI_GRAPHICS_VULKAN_IMAGE_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 ImageView;
+enum class ResourceOwnershipType
+{
+ OWNED,
+ EXTERNAL
+};
+
+class Image : public Resource
+{
+public:
+ /**
+ * Creates new VkImage with given specification, it doesn't
+ * bind the memory.
+ * @param graphics
+ * @param createInfo
+ */
+ Image(Graphics& graphics, const vk::ImageCreateInfo& createInfo);
+
+ /**
+ * Constructor creates wrapper on the VkImage coming from external
+ * source. It doesn't take over ownership so it's still owner's
+ * responsibility to destroy it and maintain the usage.
+ *
+ * @param graphics
+ * @param externalImage
+ */
+ Image(Graphics& graphics, vk::Image externalImage);
+
+ /**
+ * Destructor
+ */
+ virtual ~Image() = default;
+
+ /**
+ * Creates UNMANAGED VkImageView from the current image.
+ * Usage requires external lifecycle management and synchronization
+ * Memory MUST be bound for this function to work!
+ * @param info
+ * @return
+ */
+ vk::ImageView CreateUnmanagedView(const vk::ImageViewCreateInfo& info);
+
+ /**
+ * Creates MANAGED ImageView from the current image
+ * Memory MUST be bound for this function to work!
+ * @param info
+ * @return
+ */
+ UniqueImageView CreateView(const vk::ImageViewCreateInfo& info);
+
+ /**
+ * Returns underlying Vulkan object
+ * @return
+ */
+ vk::Image GetImage() const
+ {
+ return mImage;
+ }
+
+private:
+
+ Graphics& mGraphics;
+
+ vk::Image mImage;
+ vk::ImageLayout mLayout;
+
+ ResourceOwnershipType mOwnershipType;
+};
+
+/*
+ * ImageView
+ * todo: move it to its own file
+ */
+class ImageView : public Resource
+{
+public:
+ ImageView(Graphics& graphics, Image& image);
+ ImageView(Graphics& graphics, Image& image, const VkImageViewCreateInfo& createInfo);
+
+ virtual ~ImageView() override;
+
+ const vk::ImageView& GetImageView() const
+ {
+ return mImageView;
+ }
+
+ Image& GetImage() const
+ {
+ return mImageRef.GetResource();
+ }
+
+private:
+ Graphics& mGraphics;
+ ResourceRef<Image> mImageRef;
+
+ vk::ImageView mImageView;
+};
+
+} // namespace Vulkan
+
+} // namespace Graphics
+
+} // namespace Dali
+
+#endif // DALI_GRAPHICS_VULKAN_IMAGE_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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/graphics/vulkan/vulkan-command-buffer.h>
+#include <dali/graphics/vulkan/vulkan-fence.h>
+#include <dali/graphics/vulkan/vulkan-graphics.h>
+#include <dali/graphics/vulkan/vulkan-queue.h>
+
+namespace Dali
+{
+namespace Graphics
+{
+namespace Vulkan
+{
+
+namespace
+{
+// this class is non-copyable, just movable
+struct PrepareSemaphoresData
+{
+ PrepareSemaphoresData() = default;
+ PrepareSemaphoresData(const PrepareSemaphoresData&) = delete;
+ PrepareSemaphoresData& operator=(const PrepareSemaphoresData&) = delete;
+ PrepareSemaphoresData(PrepareSemaphoresData&&) = default;
+ PrepareSemaphoresData& operator=(PrepareSemaphoresData&&) = default;
+
+ std::vector< vk::Semaphore > signalSemaphores;
+ std::vector< vk::Semaphore > waitSemaphores;
+ std::vector< vk::PipelineStageFlags > waitDstStageMasks;
+};
+
+// helper function converting size_t to required uint32_t
+template< typename T >
+inline uint32_t u32(T val)
+{
+ return static_cast< uint32_t >(val);
+}
+
+inline PrepareSemaphoresData PrepareSemaphores(const std::vector< CommandBufferRef >& commandBuffers)
+{
+ PrepareSemaphoresData retval{};
+ for(auto& cmdbufref : commandBuffers)
+ {
+ auto& cmdbuf = cmdbufref.get();
+ if(!retval.signalSemaphores.empty())
+ {
+ retval.signalSemaphores.insert(retval.signalSemaphores.end(),
+ cmdbuf.GetSignalSemaphores().begin(),
+ cmdbuf.GetSignalSemaphores().end());
+ }
+ if(!retval.waitSemaphores.empty())
+ {
+ retval.waitSemaphores.insert(retval.waitSemaphores.end(), cmdbuf.GetSWaitSemaphores().begin(),
+ cmdbuf.GetSWaitSemaphores().end());
+ retval.waitDstStageMasks.insert(retval.waitDstStageMasks.end(),
+ cmdbuf.GetWaitSemaphoreStages().begin(),
+ cmdbuf.GetWaitSemaphoreStages().end());
+ }
+ }
+ return std::move(retval);
+}
+}
+
+// submission
+Submission::Submission(Fence& fence) : mFences(fence)
+{
+}
+
+bool Submission::WaitForFence(uint32_t timeout)
+{
+ return mFences.get().Wait(timeout);
+}
+
+// queue
+Queue::Queue(Graphics& graphics, vk::Queue queue, uint32_t queueFamilyIndex, uint32_t queueIndex,
+ vk::QueueFlags queueFlags)
+: mGraphics(graphics), mQueue(queue), mFlags(queueFlags), mQueueFamilyIndex(queueFamilyIndex), mQueueIndex(queueIndex)
+{
+}
+
+Queue::~Queue() // queues are non-destructible
+{
+}
+
+std::unique_ptr< Submission > Queue::Submit(CommandBuffer& commandBuffer, 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)
+{
+ // Prepare command buffers for submission
+ auto buffers = PrepareBuffers(commandBuffers);
+
+ auto semaphores = PrepareSemaphores(commandBuffers);
+
+ auto info = vk::SubmitInfo{};
+
+ /* semaphores per command buffer */
+ info.setCommandBufferCount(u32(commandBuffers.size()));
+ info.setPCommandBuffers(buffers.data());
+ info.setSignalSemaphoreCount(u32(semaphores.signalSemaphores.size()));
+ info.setPSignalSemaphores(semaphores.signalSemaphores.data());
+ info.setWaitSemaphoreCount(u32(semaphores.waitSemaphores.size()));
+ info.setPWaitSemaphores(semaphores.waitSemaphores.data());
+ info.setPWaitDstStageMask(semaphores.waitDstStageMasks.data());
+
+ VkAssert(mQueue.submit(1, &info, fence.GetFence()));
+
+ return MakeUnique< Submission >(fence);
+}
+#pragma GCC diagnostic pop
+
+std::vector< vk::CommandBuffer > Queue::PrepareBuffers(const std::vector< CommandBufferRef >& commandBuffers) const
+{
+ std::vector< vk::CommandBuffer > retval(commandBuffers.size());
+ for(uint32_t i = 0; i < commandBuffers.size(); ++i)
+ {
+ retval[i] = commandBuffers[i].get().Get();
+ }
+ return retval;
+}
+
+void Queue::WaitIdle() const
+{
+ assert(mQueue && "Queue isn't initialised!");
+ mQueue.waitIdle();
+}
+
+vk::Result Queue::Present(const vk::PresentInfoKHR& presentInfo)
+{
+ return VkTest(mQueue.presentKHR(presentInfo));
+}
+
+vk::Result Queue::Present(vk::SwapchainKHR swapchain, uint32_t imageIndex)
+{
+ auto info = vk::PresentInfoKHR{}
+ .setWaitSemaphoreCount(0)
+ .setPWaitSemaphores(nullptr)
+ .setPResults(nullptr)
+ .setPImageIndices(&imageIndex)
+ .setPSwapchains(&swapchain)
+ .setSwapchainCount(1);
+
+ return Present(info);
+}
+
+} // namespace Vulkan
+} // namespace Graphics
+} // namespace Dali
--- /dev/null
+#ifndef DALI_GRAPHICS_VULKAN_QUEUE_H
+#define DALI_GRAPHICS_VULKAN_QUEUE_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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/graphics/vulkan/vulkan-types.h>
+
+namespace Dali
+{
+namespace Graphics
+{
+namespace Vulkan
+{
+
+class Fence;
+class Submission
+{
+public:
+ Submission(Fence& fence);
+
+ bool WaitForFence(uint32_t timeout = 0u);
+
+private:
+ // todo: possibly resources locks stored here?
+ FenceRef mFences;
+};
+
+class Queue
+{
+public:
+ Queue() = delete;
+ Queue(Graphics& graphics, vk::Queue queue, uint32_t queueFamilyIndex, uint32_t queueIndex,
+ vk::QueueFlags queueFlags);
+ ~Queue(); // queues are non-destructible
+
+ /** Submits command buffers */
+ std::unique_ptr< Submission > Submit(const std::vector< CommandBufferRef >& commandBuffers,
+ Fence& fence);
+
+ /** Helper function to submit single command buffer */
+ std::unique_ptr< Submission > Submit(CommandBuffer& commandBuffer, Fence& fence);
+
+ void WaitIdle() const;
+
+ /**
+ *
+ * @param presentInfo
+ * @return
+ */
+ vk::Result Present( const vk::PresentInfoKHR& presentInfo );
+
+ /**
+ *
+ * @param swapchain
+ * @return
+ */
+ vk::Result Present( vk::SwapchainKHR swapchain, uint32_t imageIndex );
+
+private:
+ /** Prepares command buffers for submission */
+ std::vector< vk::CommandBuffer > PrepareBuffers(
+ const std::vector< CommandBufferRef >& commandBuffers) const;
+
+
+
+private:
+ Graphics& mGraphics;
+ vk::Queue mQueue;
+ vk::QueueFlags mFlags;
+ std::vector< vk::Fence > mFences;
+ uint32_t mQueueFamilyIndex;
+ uint32_t mQueueIndex;
+};
+
+} // namespace Vulkan
+} // namespace Graphics
+} // namespace Dali
+
+#endif // DALI_GRAPHICS_VULKAN_QUEUE_H
--- /dev/null
+/*
+ * This is the test code that allows to run Vulkan backend
+ * as standalone application. Supports both Xcb and Xlib window
+ * integration. MUST NOT BE COMPILED WITH DALI!
+ */
+
+// for surface implementation
+#ifndef VK_USE_PLATFORM_XLIB_KHR
+#define VK_USE_PLATFORM_XLIB_KHR
+#endif
+#ifndef VK_USE_PLATFORM_XCB_KHR
+#define VK_USE_PLATFORM_XCB_KHR
+#endif
+
+#include <vulkan/vulkan.hpp>
+
+#include <dali/integration-api/graphics/vulkan/vk-surface-factory.h>
+#include <dali/integration-api/graphics/graphics.h>
+#include <xcb/xcb.h>
+#include <unistd.h>
+
+#define USE_XLIB 0
+
+using Dali::Integration::Graphics::Graphics;
+using Dali::Integration::Graphics::Vulkan::VkSurfaceFactory;
+
+template< typename T, typename... Args >
+std::unique_ptr< T > MakeUnique(Args&&... args)
+{
+ return std::unique_ptr< T >(new T(std::forward< Args >(args)...));
+}
+
+
+class VkSurfaceXlib : public Dali::Integration::Graphics::Vulkan::VkSurfaceFactory
+{
+public:
+ /**
+ * Instantiates surface factory ( should
+ * @param display
+ * @param window
+ */
+ VkSurfaceXlib(Display* display, Window window)
+ : VkSurfaceFactory(), mDisplay(display), mWindow(window)
+ {
+ }
+
+ virtual vk::SurfaceKHR Create(vk::Instance instance, vk::AllocationCallbacks* allocCallbacks,
+ vk::PhysicalDevice physicalDevice) const override
+ {
+ vk::XlibSurfaceCreateInfoKHR info;
+ info.setDpy(mDisplay).setWindow(mWindow);
+ auto retval = instance.createXlibSurfaceKHR(info, allocCallbacks).value;
+ return retval;
+ }
+
+private:
+ Display* mDisplay;
+ Window mWindow;
+ vk::SurfaceKHR mSurface;
+};
+
+class VkSurfaceXcb : public Dali::Integration::Graphics::Vulkan::VkSurfaceFactory
+{
+public:
+ /**
+ * Instantiates surface factory ( should
+ * @param display
+ * @param window
+ */
+ VkSurfaceXcb(xcb_connection_t* connection, xcb_window_t window)
+ : VkSurfaceFactory{}, mConnection(connection), mWindow(window)
+ {
+ }
+
+ virtual vk::SurfaceKHR Create(vk::Instance instance, vk::AllocationCallbacks* allocCallbacks,
+ vk::PhysicalDevice physicalDevice) const override
+ {
+ vk::XcbSurfaceCreateInfoKHR info;
+ info.setConnection(mConnection).setWindow(mWindow);
+ auto retval = instance.createXcbSurfaceKHR(info, allocCallbacks).value;
+ return retval;
+ }
+
+private:
+ xcb_connection_t* mConnection;
+ xcb_window_t mWindow;
+ vk::SurfaceKHR mSurface;
+};
+
+namespace Test
+{
+struct xlib_window_t
+{
+ uint32_t width{0u};
+ uint32_t height{0u};
+ Window window{};
+ Display* display{nullptr};
+
+ ~xlib_window_t()
+ {
+ XDestroyWindow(display, window);
+ }
+};
+
+std::unique_ptr< xlib_window_t > create_xlib_window(int width, int height)
+{
+ std::unique_ptr< xlib_window_t > wnd{new xlib_window_t};
+ // 1. Create Window ( done by DALI
+
+ wnd->width = width;
+ wnd->height = height;
+ wnd->display = XOpenDisplay(nullptr);
+ auto defaultScreen = DefaultScreen(wnd->display);
+ wnd->window =
+ XCreateSimpleWindow(wnd->display, RootWindow(wnd->display, defaultScreen), 0, 0, wnd->width,
+ wnd->height, 1, BlackPixel(wnd->display, defaultScreen),
+ WhitePixel(wnd->display, defaultScreen));
+
+ XSelectInput(wnd->display, wnd->window, ExposureMask | KeyPressMask);
+ XMapWindow(wnd->display, wnd->window);
+ XSync(wnd->display, false);
+
+ return wnd;
+}
+
+struct xcb_window_t
+{
+ uint32_t width{0u};
+ uint32_t height{0u};
+ ::xcb_window_t window;
+ xcb_connection_t* connection;
+
+ ~xcb_window_t()
+ {
+ xcb_destroy_window(connection, window);
+ }
+};
+
+std::unique_ptr< Test::xcb_window_t > create_xcb_window(int width, int height)
+{
+ std::unique_ptr< Test::xcb_window_t > wnd{new Test::xcb_window_t};
+ // 1. Create Window ( done by DALI
+
+ wnd->width = width;
+ wnd->height = height;
+
+ int screenNum(0);
+
+ xcb_connection_t* connection = xcb_connect(NULL, &screenNum);
+ const xcb_setup_t* setup = xcb_get_setup(connection);
+ xcb_screen_iterator_t iter = xcb_setup_roots_iterator(setup);
+ for(int i = 0; i < screenNum; ++i)
+ xcb_screen_next(&iter);
+
+ xcb_screen_t* screen = iter.data;
+ ::xcb_window_t window = xcb_generate_id(connection);
+
+ uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
+ uint32_t values[] = {screen->white_pixel, XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS};
+
+ xcb_create_window(connection, XCB_COPY_FROM_PARENT, window, screen->root, 0, 0, wnd->width,
+ wnd->height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, mask,
+ values);
+
+ xcb_map_window(connection, window);
+ const uint32_t coords[] = {100, 100};
+ xcb_configure_window(connection, window, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, coords);
+ xcb_flush(connection);
+
+ wnd->connection = connection;
+ wnd->window = window;
+
+ return wnd;
+}
+}
+
+namespace VulkanTest
+{
+int RunTestMain()
+{
+
+#if USE_XLIB == 1
+ auto window = Test::create_xlib_window(640, 480);
+ auto surfaceFactory =
+ std::unique_ptr< VkSurfaceXlib >{new VkSurfaceXlib{window->display, window->window}};
+#else
+ auto window = Test::create_xcb_window(640, 480);
+ auto surfaceFactory =
+ std::unique_ptr<VkSurfaceXcb>{new VkSurfaceXcb{window->connection, window->window}};
+#endif
+
+ auto graphics = MakeUnique<Graphics>();
+ auto fbid = graphics->Create( std::move(surfaceFactory) );
+
+ while(1)
+ {
+ graphics->PreRender( fbid );
+ graphics->PostRender( fbid );
+ }
+ return 0;
+}
+}
--- /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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/graphics/vulkan/vulkan-command-buffer.h>
+#include <dali/graphics/vulkan/vulkan-command-pool.h>
+#include <dali/graphics/vulkan/vulkan-fence.h>
+#include <dali/graphics/vulkan/vulkan-graphics.h>
+#include <dali/graphics/vulkan/vulkan-queue.h>
+#include <dali/graphics/vulkan/vulkan-surface.h>
+#include <dali/graphics/vulkan/vulkan-image.h>
+
+namespace Dali
+{
+namespace Graphics
+{
+namespace Vulkan
+{
+
+namespace
+{
+// constants
+auto VK_COMPONENT_MAPPING_RGBA = vk::ComponentMapping{}
+ .setR(vk::ComponentSwizzle::eR)
+ .setG(vk::ComponentSwizzle::eG)
+ .setB(vk::ComponentSwizzle::eB)
+ .setA(vk::ComponentSwizzle::eA);
+}
+
+SwapchainImage::SwapchainImage() = default;
+SwapchainImage::~SwapchainImage() = default;
+
+Surface::Surface(Graphics& graphics, vk::SurfaceKHR surface, uint32_t bufferCount, bool hasDepthStencil)
+: mGraphics(graphics), mSurface(surface), mSwapchain{nullptr}, mBufferCount{bufferCount}, mHasDepthStencil(hasDepthStencil)
+{
+}
+
+Surface::~Surface()
+{
+ if(mSwapchain)
+ {
+ DestroySwapchain();
+ }
+ if(mSurface)
+ {
+ mGraphics.GetInstance().destroySurfaceKHR(mSurface, mGraphics.GetAllocator());
+ }
+}
+
+void Surface::AcquireNextImage()
+{
+ // if swapchain hasn't been created yet, create it
+ // TODO: deferring may bring a lag when surface is swapped very first time
+ // it might be good to have an option to create swapchain regardless further usage
+ if(!mSwapchain)
+ {
+ CreateSwapchain();
+ }
+
+ if(!mFrameFence)
+ {
+ mFrameFence = MakeUnique< Fence >(mGraphics);
+ }
+
+ // acquire image, for simplicity using fence for acquiring as it is unknown what next command buffer will
+ // be executed yet
+ mFrameFence->Reset();
+ uint32_t index = VkAssert(mGraphics.GetDevice().acquireNextImageKHR(mSwapchain, 1000000, nullptr,
+ mFrameFence->GetFence()));
+ mFrameFence->Wait();
+ mFrameFence->Reset();
+
+ mCurrentBufferIndex = index;
+
+ auto& swapImage = mSwapImages[index];
+
+ // change layout if necessary to color attachment
+ if(swapImage.layout != vk::ImageLayout::eColorAttachmentOptimal)
+ {
+ auto& queue = mGraphics.GetGraphicsQueue();
+ queue.Submit(*swapImage.layoutToColorCmdBuf.get(), *mFrameFence.get())->WaitForFence();
+ }
+
+ mFrameFence->Reset();
+
+ // todo: anything to be done before beginning main command buffer?
+ BeginRenderPass();
+}
+
+void Surface::BeginRenderPass()
+{
+ auto& swapImage = mSwapImages[mCurrentBufferIndex];
+
+ // begin command buffer ( can be directly obtained through Graphics( surface )
+ swapImage.mainCmdBuf->Begin(vk::CommandBufferUsageFlagBits::eOneTimeSubmit);
+
+ /*
+ * 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();
+ {
+ std::array< vk::ClearValue, 2 > clearValues;
+
+ static float r = 0.0f;
+ r += 0.01f;
+ if(r > 1.0f)
+ r -= 1.0f;
+
+ clearValues[0].color.setFloat32({r, 0.0f, 0.0f, 1.0f});
+ clearValues[1].depthStencil.setDepth(1.0f).setStencil(0.0f);
+
+ auto rpInfo = vk::RenderPassBeginInfo{};
+ rpInfo.setRenderPass(mDefaultRenderPass)
+ .setFramebuffer(swapImage.framebuffer)
+ .setRenderArea(vk::Rect2D{}.setOffset({0, 0}).setExtent(mExtent))
+ .setClearValueCount(mHasDepthStencil ? 2 : 1)
+ .setPClearValues(clearValues.data());
+
+ auto subpassContents = vk::SubpassContents{vk::SubpassContents::eInline};
+ vkCmdBuf.beginRenderPass(rpInfo, subpassContents);
+ }
+}
+
+void Surface::EndRenderPass()
+{
+ // todo: use semaphores and do not create fences all over again
+ auto& swapImage = mSwapImages[mCurrentBufferIndex];
+ auto vkCmdBuf = swapImage.mainCmdBuf->Get();
+
+ // complete render pass
+ vkCmdBuf.endRenderPass();
+
+ // finalize command buffer
+ swapImage.mainCmdBuf->End();
+
+ // submit
+ auto& queue = mGraphics.GetGraphicsQueue();
+ queue.Submit(*swapImage.mainCmdBuf.get(), *mFrameFence.get())->WaitForFence();
+}
+
+void Surface::Present()
+{
+ // complete render pass and command buffer
+ EndRenderPass();
+
+ auto& swapImage = mSwapImages[mCurrentBufferIndex];
+ auto result = mGraphics.GetGraphicsQueue().Present(mSwapchain, mCurrentBufferIndex);
+ if(result != vk::Result::eSuccess)
+ {
+ //todo: handle swapchain invalidation
+ }
+ swapImage.layout = vk::ImageLayout::ePresentSrcKHR;
+ // todo: test result against swapchain expiration
+}
+
+void Surface::CreateSwapchain()
+{
+ {
+ auto formats = VkAssert(mGraphics.GetPhysicalDevice().getSurfaceFormatsKHR(mSurface));
+ // find first which is not UNDEFINED
+ mFormat = vk::Format::eUndefined;
+ for(auto& format : formats)
+ {
+ if(format.format != vk::Format::eUndefined && mFormat == vk::Format::eUndefined)
+ {
+ mFormat = format.format;
+ mColorSpace = format.colorSpace;
+ }
+ }
+ }
+
+ assert(mFormat != vk::Format::eUndefined && "No supported surface format!");
+
+ mCapabilities.reset(new vk::SurfaceCapabilitiesKHR(
+ VkAssert(mGraphics.GetPhysicalDevice().getSurfaceCapabilitiesKHR(mSurface))));
+
+ mExtent = mCapabilities->currentExtent;
+
+ CreateVulkanSwapchain();
+
+ // initialise default render pass
+ InitialiseRenderPass();
+
+ // if successful continue with obtaining images etc. also each swapchain will obtain default renderpass
+ InitialiseSwapchain();
+
+ // prerecord command buffers per each image in order to provide layout transition
+ CreateCommandBuffers();
+}
+
+void Surface::CreateVulkanSwapchain()
+{
+ auto info = vk::SwapchainCreateInfoKHR{};
+
+ info.setClipped(true)
+ .setCompositeAlpha(vk::CompositeAlphaFlagBitsKHR::eOpaque)
+ .setImageArrayLayers(1)
+ .setImageColorSpace(mColorSpace)
+ .setImageExtent(mCapabilities->currentExtent)
+ .setImageFormat(mFormat)
+ .setImageSharingMode(vk::SharingMode::eExclusive)
+ .setImageUsage(vk::ImageUsageFlagBits::eColorAttachment)
+ .setMinImageCount(mBufferCount)
+ .setPresentMode(vk::PresentModeKHR::eFifo)
+ .setPreTransform(mCapabilities->currentTransform)
+ .setOldSwapchain(nullptr)
+ .setPQueueFamilyIndices(nullptr)
+ .setQueueFamilyIndexCount(0)
+ .setSurface(mSurface);
+
+ mSwapchain = VkAssert(mGraphics.GetDevice().createSwapchainKHR(
+ reinterpret_cast< vk::SwapchainCreateInfoKHR& >(info), mGraphics.GetAllocator()));
+}
+
+void Surface::DestroySwapchain()
+{
+ mGraphics.GetDevice().destroySwapchainKHR(mSwapchain, mGraphics.GetAllocator());
+}
+
+void Surface::InitialiseSwapchain()
+{
+ const auto& device = mGraphics.GetDevice();
+
+ auto images = VkAssert(device.getSwapchainImagesKHR(mSwapchain));
+ assert(mBufferCount == images.size() && "Swapchain images count not equal requested value!");
+
+ {
+ auto swapImages = std::vector< SwapchainImage >{};
+
+ // for each image create framebuffer and image view
+ for(auto& image : images)
+ {
+ AddSwapchainImage(image, swapImages);
+ }
+
+ mSwapImages = std::move(swapImages);
+ }
+
+ if(mHasDepthStencil)
+ {
+ CreateDepthStencil();
+ }
+}
+
+void Surface::AddSwapchainImage(vk::Image image, std::vector< SwapchainImage >& swapchainImages)
+{
+ auto swapImage = std::move(SwapchainImage{});
+ swapImage.image = MakeUnique<Image>( mGraphics, image );
+
+ // create ImageView
+ CreateImageView(swapImage);
+
+ // Create framebuffer ( there must be already render pass and information whether
+ // we use depth or not )
+ CreateFramebuffer(swapImage);
+
+ // initialise semaphores
+ CreateSemaphores(swapImage);
+
+ swapImage.layout = vk::ImageLayout::eUndefined;
+
+ swapchainImages.push_back(std::move(swapImage));
+}
+
+void Surface::CreateImageView(SwapchainImage& swapImage)
+{
+ // Simple image view 2D as a color attachment
+ auto ivInfo = vk::ImageViewCreateInfo{};
+ ivInfo.setFormat(mFormat)
+ .setComponents(VK_COMPONENT_MAPPING_RGBA)
+ .setImage(swapImage.image->GetImage())
+ .setSubresourceRange(vk::ImageSubresourceRange()
+ .setAspectMask(vk::ImageAspectFlagBits::eColor)
+ .setBaseArrayLayer(0)
+ .setBaseMipLevel(0)
+ .setLayerCount(1)
+ .setLevelCount(1))
+ .setViewType(vk::ImageViewType::e2D);
+
+ swapImage.imageView = swapImage.image->CreateView( ivInfo );
+}
+
+void Surface::CreateFramebuffer(SwapchainImage& swapImage)
+{
+ vk::FramebufferCreateInfo fbInfo;
+ fbInfo.setAttachmentCount(mHasDepthStencil ? 2 : 1)
+ .setPAttachments(&swapImage.imageView->GetImageView()) // todo: add depth/stencil attachment
+ .setHeight(mExtent.height)
+ .setWidth(mExtent.width)
+ .setLayers(1)
+ .setRenderPass(mDefaultRenderPass);
+
+ swapImage.framebuffer =
+ VkAssert(mGraphics.GetDevice().createFramebuffer(fbInfo, mGraphics.GetAllocator()));
+}
+
+void Surface::CreateSemaphores(SwapchainImage& swapImage)
+{
+ swapImage.acqSem =
+ VkAssert(mGraphics.GetDevice().createSemaphore(vk::SemaphoreCreateInfo(), mGraphics.GetAllocator()));
+ swapImage.presentSem =
+ VkAssert(mGraphics.GetDevice().createSemaphore(vk::SemaphoreCreateInfo(), mGraphics.GetAllocator()));
+}
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wframe-larger-than="
+void Surface::InitialiseRenderPass()
+{
+ auto att = std::vector<vk::AttachmentDescription>{ 2 };
+
+ // color attachment
+ att[0]
+ .setFormat(mFormat)
+ .setLoadOp(vk::AttachmentLoadOp::eClear)
+ .setStoreOp(vk::AttachmentStoreOp::eStore)
+ .setSamples(vk::SampleCountFlagBits::e1)
+ .setStencilLoadOp(vk::AttachmentLoadOp::eDontCare)
+ .setStencilStoreOp(vk::AttachmentStoreOp::eDontCare)
+ .setInitialLayout(vk::ImageLayout::eColorAttachmentOptimal)
+ .setFinalLayout(vk::ImageLayout::ePresentSrcKHR);
+
+ // optional depth/stencil attachment
+ att[1]
+ .setFormat(mDepthStencilFormat)
+ .setLoadOp(vk::AttachmentLoadOp::eClear)
+ .setStoreOp(vk::AttachmentStoreOp::eDontCare)
+ .setSamples(vk::SampleCountFlagBits::e1)
+ .setStencilLoadOp(vk::AttachmentLoadOp::eDontCare)
+ .setStencilStoreOp(vk::AttachmentStoreOp::eDontCare)
+ .setInitialLayout(vk::ImageLayout::eDepthStencilAttachmentOptimal)
+ .setFinalLayout(vk::ImageLayout::eDepthStencilAttachmentOptimal);
+
+ auto attRef = std::array<vk::AttachmentReference, 2>{};
+ attRef[0].setLayout(vk::ImageLayout::eColorAttachmentOptimal).setAttachment(0);
+ attRef[1].setLayout(vk::ImageLayout::eDepthStencilAttachmentOptimal).setAttachment(1);
+
+ // prepare default subpass
+ vk::SubpassDescription subpass;
+ subpass.setColorAttachmentCount(1)
+ .setPColorAttachments(&attRef[0])
+ .setPDepthStencilAttachment(mHasDepthStencil ? &attRef[1] : nullptr)
+ .setPipelineBindPoint(vk::PipelineBindPoint::eGraphics);
+
+ vk::RenderPassCreateInfo info;
+ info.setPAttachments(att.data()).setAttachmentCount(mHasDepthStencil ? 2 : 1).setPSubpasses(&subpass).setSubpassCount(1);
+
+ mDefaultRenderPass = VkAssert(mGraphics.GetDevice().createRenderPass(info, mGraphics.GetAllocator()));
+}
+#pragma GCC diagnostic pop
+
+void Surface::CreateDepthStencil()
+{
+ assert("Surface::CreateDepthStencil() not implemented!");
+ /// todo: implement
+}
+
+void Surface::DestroyDepthStencil()
+{
+ /// todo: implement
+ assert("Surface::DestroyDepthStencil() not implemented!");
+}
+
+void Surface::CreateCommandBuffers()
+{
+ if(!mCommandPool)
+ {
+ auto info = vk::CommandPoolCreateInfo{}.setFlags(vk::CommandPoolCreateFlagBits::eResetCommandBuffer);
+ info.setQueueFamilyIndex(0); // todo: get correct queue family index ( 0 works by default ;) )
+ mCommandPool = MakeUnique< CommandPool >(mGraphics, info);
+ }
+
+ // allocate command buffers
+ auto cmdBuffers = std::vector< CommandBufferRef >{};
+ auto cmdInfo =
+ vk::CommandBufferAllocateInfo{}.setCommandBufferCount(1).setLevel(vk::CommandBufferLevel::ePrimary);
+
+ for(auto& swapImage : mSwapImages)
+ {
+ swapImage.layoutToColorCmdBuf = mCommandPool->AllocateCommandBuffer(cmdInfo);
+ swapImage.mainCmdBuf = mCommandPool->AllocateCommandBuffer(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->Begin();
+ swapImage.layoutToColorCmdBuf->ImageLayoutTransition(swapImage.image->GetImage(),
+ swapImage.layout,
+ vk::ImageLayout::eColorAttachmentOptimal,
+ vk::ImageAspectFlagBits::eColor);
+ swapImage.layoutToColorCmdBuf->End();
+ swapImage.layout = vk::ImageLayout::eColorAttachmentOptimal;
+
+ cmdBuffers.push_back(std::ref(*swapImage.layoutToColorCmdBuf.get()));
+ }
+
+ // submit to the queue
+ {
+ auto& queue = mGraphics.GetGraphicsQueue();
+ auto fence = Fence(mGraphics);
+ auto submission = queue.Submit(cmdBuffers, fence);
+ submission->WaitForFence();
+ }
+
+ // record present to color transitions for each buffer for further reusing
+ for(auto& swapImage : mSwapImages)
+ {
+ swapImage.layoutToColorCmdBuf->Reset();
+ swapImage.layoutToColorCmdBuf->Begin();
+ swapImage.layoutToColorCmdBuf->ImageLayoutTransition(swapImage.image->GetImage(),
+ vk::ImageLayout::ePresentSrcKHR,
+ vk::ImageLayout::eColorAttachmentOptimal,
+ vk::ImageAspectFlagBits::eColor);
+ swapImage.layoutToColorCmdBuf->End();
+ swapImage.layout = vk::ImageLayout::eColorAttachmentOptimal;
+ }
+}
+
+vk::SurfaceKHR Surface::GetSurfaceKHR() const
+{
+ return mSurface;
+}
+
+vk::RenderPass Surface::GetRenderPass() const
+{
+ return mDefaultRenderPass;
+}
+
+vk::Framebuffer Surface::GetFramebuffer(uint32_t index) const
+{
+ return mSwapImages[index].framebuffer;
+}
+
+ImageView& Surface::GetImageView(uint32_t index) const
+{
+ return *mSwapImages[index].imageView;
+}
+
+Image& Surface::GetImage(uint32_t index) const
+{
+ return *mSwapImages[index].image;
+}
+
+} // namespace Vulkan
+} // namespace Graphics
+} // namespace Dali
--- /dev/null
+#ifndef DALI_GRAPHICS_VULKAN_SURFACE_H
+#define DALI_GRAPHICS_VULKAN_SURFACE_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.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include <dali/graphics/vulkan/vulkan-types.h>
+
+namespace Dali
+{
+namespace Graphics
+{
+namespace Vulkan
+{
+
+/**
+ * Vulkan surface is coupled with swapchain -> one swapchain per surface
+ * Swapchain won't exist until surface is used in a such way
+ *
+ */
+class Graphics;
+class CommandBuffer;
+class CommandPool;
+class Surface;
+
+using UniqueSurface = std::unique_ptr< Surface >;
+using UniqueCommandBuffer = std::unique_ptr< CommandBuffer >;
+using UniqueCommandPool = std::unique_ptr< CommandPool >;
+
+// simple structure describing single image of swapchain
+// non-copyable, only movable
+struct SwapchainImage
+{
+ SwapchainImage();
+ ~SwapchainImage();
+ SwapchainImage(const SwapchainImage&) = delete;
+ SwapchainImage(SwapchainImage&&) = default;
+ SwapchainImage& operator=(const SwapchainImage&) = delete;
+ SwapchainImage& operator=(SwapchainImage&&) = default;
+
+ UniqueImage image;
+ UniqueImageView imageView;
+ vk::Framebuffer framebuffer;
+ vk::ImageLayout layout;
+ vk::Semaphore acqSem;
+ vk::Semaphore presentSem;
+
+ // layout transitions, prerecorded command buffers
+ UniqueCommandBuffer layoutToColorCmdBuf;
+ UniqueCommandBuffer mainCmdBuf;
+};
+
+class Surface
+{
+public:
+ Surface(Graphics& graphics, vk::SurfaceKHR surface, uint32_t bufferCount = 2,
+ bool hasDepthStencil = false);
+ ~Surface();
+
+ /**
+ * Prepares new swapchain image
+ */
+ void AcquireNextImage();
+
+ /**
+ * Presents image
+ */
+ void Present();
+
+ /**
+ *
+ * @return
+ */
+ vk::RenderPass GetRenderPass() const;
+
+ /**
+ *
+ * @param index
+ * @return
+ */
+ vk::Framebuffer GetFramebuffer(uint32_t index = -1u) const;
+
+ /**
+ *
+ * @param index
+ * @return
+ */
+ ImageView& GetImageView(uint32_t index = -1u) const;
+
+ /**
+ *
+ * @param index
+ * @return
+ */
+ Image& GetImage(uint32_t index = -1u) const;
+
+ /**
+ *
+ * @return
+ */
+ vk::SurfaceKHR GetSurfaceKHR() const;
+
+private:
+ void CreateSwapchain();
+
+ void CreateVulkanSwapchain();
+
+ void CreateImageView(SwapchainImage& swapImage);
+ void CreateFramebuffer(SwapchainImage& swapImage);
+ void CreateSemaphores(SwapchainImage& swapImage);
+
+ void DestroySwapchain();
+
+ void InitialiseSwapchain();
+
+ void InitialiseRenderPass();
+
+ void AddSwapchainImage(vk::Image image, std::vector< SwapchainImage >& swapchainImages);
+
+ void CreateCommandBuffers();
+
+ void CreateDepthStencil();
+
+ void DestroyDepthStencil();
+
+ void BeginRenderPass();
+
+ void EndRenderPass();
+
+ Graphics& mGraphics;
+ vk::SurfaceKHR mSurface;
+ vk::SwapchainKHR mSwapchain;
+
+ vk::Format mDepthStencilFormat{vk::Format::eD16UnormS8Uint};
+ vk::Image mDepthStencilImage;
+ vk::ImageView mDepthStencilImageView;
+ vk::DeviceMemory mDepthStencilMemory;
+
+ UniqueCommandPool mCommandPool;
+
+ vk::Format mFormat;
+ vk::ColorSpaceKHR mColorSpace;
+ vk::Extent2D mExtent;
+
+ std::vector< SwapchainImage > mSwapImages;
+ std::unique_ptr< vk::SurfaceCapabilitiesKHR > mCapabilities;
+
+ UniqueFence mFrameFence;
+
+ vk::RenderPass mDefaultRenderPass;
+ uint32_t mBufferCount;
+ uint32_t mCurrentBufferIndex;
+ bool mHasDepthStencil;
+};
+
+} // namespace Vulkan
+} // namespace Graphics
+} // namespace Dali
+
+#endif // DALI_GRAPHICS_VULKAN_SURFACE_H
--- /dev/null
+#ifndef DALI_GRAPHICS_VULKAN_TYPES_H
+#define DALI_GRAPHICS_VULKAN_TYPES_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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+
+// Vulkan
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#include <vulkan/vulkan.hpp>
+#pragma GCC diagnostic pop
+
+// StdC++
+#include <atomic>
+#include <unordered_map>
+
+#ifndef VULKAN_HPP_NO_EXCEPTIONS
+#define VULKAN_HPP_NO_EXCEPTIONS
+#endif
+
+namespace Dali
+{
+namespace Graphics
+{
+
+template< typename T, typename... Args >
+std::unique_ptr< T > MakeUnique(Args&&... args)
+{
+ return std::unique_ptr< T >(new T(std::forward< Args >(args)...));
+}
+
+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)
+{
+ assert(result.result == expected);
+ return result.value;
+}
+
+inline vk::Result VkAssert(vk::Result result, vk::Result expected = vk::Result::eSuccess)
+{
+ assert(result == expected);
+ return result;
+}
+
+inline vk::Result VkTest(vk::Result result, vk::Result expected = vk::Result::eSuccess)
+{
+ // todo: log if result different than expected?
+ return result;
+}
+
+template< typename T >
+inline uint32_t U32(T value)
+{
+ return static_cast< uint32_t >(value);
+}
+
+class Resource
+{
+public:
+ Resource() : mUserCount{0u} {}
+ virtual ~Resource() = default;
+
+ void IncreaseUserCount()
+ {
+ ++mUserCount;
+ }
+
+ void DecreaseUserCount()
+ {
+ --mUserCount;
+ }
+
+ uint32_t GetUserCount() const
+ {
+ return mUserCount;
+ }
+
+private:
+
+ std::atomic<uint32_t> mUserCount;
+};
+
+template< typename T>
+class ResourceRef
+{
+public:
+
+ ResourceRef( T& object )
+ : mObject( &object )
+ {
+ mObject->IncreaseUserCount();
+ }
+
+ ResourceRef( ResourceRef& object )
+ {
+ if(mObject)
+ {
+ mObject->DecreaseUserCount();
+ }
+
+ mObject = object.mObject;
+ mObject->IncreaseUserCount();
+ }
+
+ ResourceRef operator=(ResourceRef& object )
+ {
+ if(mObject)
+ {
+ mObject->DecreaseUserCount();
+ }
+
+ mObject = object.mObject;
+ mObject->IncreaseUserCount();
+ }
+
+ ~ResourceRef()
+ {
+ if(mObject)
+ {
+ mObject->DecreaseUserCount();
+ }
+ }
+
+ T& GetResource() const
+ {
+ return *mObject;
+ }
+
+private:
+
+ T* mObject;
+};
+
+using FBID = uint32_t;
+
+#define NotImplemented() \
+{\
+printf("Function %s isn't implemented!\n", __FUNCTION__);\
+assert( "Function no implemented" );\
+}
+
+/*
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wframe-larger-than="
+#pragma GCC diagnostic pop
+*/
+} // namespace Vulkan
+} // namespace Graphics
+} // namespace Dali
+
+#endif // DALI_GRAPHICS_VULKAN_TYPES_H
$(platform_abstraction_src_dir)/system-overlay.h \
$(platform_abstraction_src_dir)/lockless-buffer.h
+graphics_integration_header_files = \
+ $(platform_abstraction_src_dir)/graphics/graphics.h \
+ $(platform_abstraction_src_dir)/graphics/surface-factory.h \
+ $(platform_abstraction_src_dir)/graphics/vulkan/vk-surface-factory.h
+
platform_abstraction_events_header_files = \
$(platform_abstraction_src_dir)/events/event.h \
$(platform_abstraction_src_dir)/events/gesture-event.h \
--- /dev/null
+# Add graphics integration source files here
+
+graphics_integration_src_files = \
+ $(graphics_integration_dir)/graphics.cpp
+
+graphics_integration_header_files = \
+ $(graphics_integration_dir)/graphics.h \
+ $(graphics_integration_dir)/surface-factory.h \
+ $(graphics_integration_dir)/vulkan/vk-surface-factory.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/vulkan-types.h>
+#include <dali/graphics/vulkan/vulkan-graphics.h>
+#include <dali/graphics/vulkan/vulkan-surface.h>
+
+#include <dali/integration-api/graphics/graphics.h>
+#include <dali/integration-api/graphics/surface-factory.h>
+
+
+namespace Dali
+{
+/// fixme: substituting directly the vulkan implementation
+namespace Graphics
+{
+using GraphicsImpl = Dali::Graphics::Vulkan::Graphics;
+}
+
+namespace Integration
+{
+namespace Graphics
+{
+
+Graphics::Graphics()
+{
+ // create device
+ auto impl = Dali::Graphics::MakeUnique<Dali::Graphics::GraphicsImpl>();
+
+ impl->Create();
+
+ mGraphicsImpl = std::move(impl);
+}
+
+Graphics::~Graphics() = default;
+
+Dali::Graphics::FBID Graphics::Create(
+ std::unique_ptr<Dali::Integration::Graphics::SurfaceFactory> surfaceFactory)
+{
+
+ // create surface
+ auto retval = mGraphicsImpl->CreateSurface(std::move(surfaceFactory));
+
+ // create device
+ mGraphicsImpl->CreateDevice();
+
+ return retval;
+}
+
+Dali::Graphics::FBID Graphics::CreateSurface(
+ std::unique_ptr<Dali::Integration::Graphics::SurfaceFactory> surfaceFactory)
+{
+ return 0u;
+}
+
+void Graphics::PreRender(Dali::Graphics::FBID framebufferId)
+{
+ assert(framebufferId != 0u && "Invalid FBID!");
+ auto &surface = mGraphicsImpl->GetSurface(framebufferId);
+ surface.AcquireNextImage();
+}
+
+/*
+ * Postrender
+ */
+void Graphics::PostRender(Dali::Graphics::FBID framebufferId)
+{
+ assert(framebufferId != 0u && "Invalid FBID!");
+ auto &surface = mGraphicsImpl->GetSurface(framebufferId);
+ surface.Present();
+}
+
+void IncludeThisLibrary()
+{
+// dummy function to create linker dependency
+}
+
+} // Namespace Graphics
+} // Namespace Integration
+} // Namespace Dali
\ No newline at end of file
--- /dev/null
+#ifndef DALI_INTEGRATION_GRAPHICS_H
+#define DALI_INTEGRATION_GRAPHICS_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.
+ *
+ */
+
+// EXTERNAL INCLUDES
+#include <memory>
+
+#define EXPORT_API __attribute__ ((visibility ("default")))
+
+namespace Dali
+{
+namespace Graphics
+{
+
+// frame buffer id
+using FBID = uint32_t;
+
+namespace Vulkan
+{
+class Graphics;
+} // Vulkan
+using GraphicsImpl = Vulkan::Graphics;
+
+} // Graphics
+
+namespace Integration
+{
+namespace Graphics
+{
+class SurfaceFactory;
+class EXPORT_API Graphics final
+{
+public:
+
+
+ Graphics();
+ ~Graphics();
+
+ /**
+ *
+ * @param surfaceFactory
+ * @return
+ */
+ Dali::Graphics::FBID CreateSurface( std::unique_ptr<Dali::Integration::Graphics::SurfaceFactory> surfaceFactory );
+
+
+ /**
+ * When creating Graphics at least one surfaceFactory must be supplied ( no headless mode )
+ * @param surfaceFactory
+ * @return
+ */
+ Dali::Graphics::FBID Create( std::unique_ptr<Dali::Integration::Graphics::SurfaceFactory> surfaceFactory );
+
+ /**
+ * Prerender
+ */
+ void PreRender( Dali::Graphics::FBID framebufferId = 0u );
+
+ /*
+ * Postrender
+ */
+ void PostRender( Dali::Graphics::FBID framebufferId = 0u );
+
+private:
+
+ std::unique_ptr<Dali::Graphics::GraphicsImpl> mGraphicsImpl;
+};
+
+/**
+ * fixme: dummy function to make sure the static library won't be discarded entirely during linking
+ */
+void IncludeThisLibrary();
+
+} // Namespace Graphics
+} // Namespace Integration
+} // Namespace Dali
+
+#endif // DALI_INTEGRATION_GRAPHICS_H
*
*/
-#ifndef DALI_CORE_GRAPHICS_VULKAN_IMAGEVIEW_H
-#define DALI_CORE_GRAPHICS_VULKAN_IMAGEVIEW_H
-
-#include <dali/graphics/vulkan/common.h>
+#ifndef DALI_INTEGRATION_GRAPHICS_SURFACE_FACTORY_H
+#define DALI_INTEGRATION_GRAPHICS_SURFACE_FACTORY_H
namespace Dali
{
-namespace Graphics
+namespace Integration
{
-namespace Vulkan
+namespace Graphics
{
-class ImageView : public VkHandle
+class SurfaceFactory
{
- OBJECT_HANDLE(ImageView)
-
+public:
+ SurfaceFactory() = default;
+ virtual ~SurfaceFactory() = default;
};
-} // namespace Vulkan
-} // namespace Graphics
-} // namespace Dali
-
+} // Namespace Graphics
+} // Namespace Integration
+} // Namespace Dali
-#endif //DALI_CORE_GRAPHICS_VULKAN_IMAGEVIEW_H
+#endif // DALI_INTEGRATION_GRAPHICS_SURFACE_FACTORY_H
--- /dev/null
+#ifndef DALI_GRAPHICS_VULKAN_VKSURFACEFACTORY_H
+#define DALI_GRAPHICS_VULKAN_VKSURFACEFACTORY_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.
+ *
+ */
+
+// INTERNAL INCLUDES
+
+#include <dali/integration-api/graphics/surface-factory.h>
+
+// EXTERNAL INCLUDES
+// Vulkan
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+#include <vulkan/vulkan.hpp>
+#pragma GCC diagnostic pop
+
+namespace Dali
+{
+namespace Integration
+{
+namespace Graphics
+{
+namespace Vulkan
+{
+
+class VkSurfaceFactory : public SurfaceFactory
+{
+public:
+
+ VkSurfaceFactory() = default;
+
+ virtual vk::SurfaceKHR Create(vk::Instance instance, vk::AllocationCallbacks *allocCallbacks,
+ vk::PhysicalDevice physicalDevice) const = 0;
+};
+
+} // namespace Vulkan
+} // namespace Graphics
+} // namespace Integration
+} // namespace Dali
+
+#endif // DALI_GRAPHICS_VULKAN_VKSURFACEFACTORY_H