/*!
* @defgroup device Device
- * @brief bind vulkan context and vkvg.
+ * @brief create or use an existing vulkan context for vkvg.
*
* #VkvgDevice is the starting point of a vkvg rendering infrastructure. It connects an
- * existing vulkan context with vkvg.
+ * existing vulkan context with vkvg, or may create a new one.
*
* Most of the vulkan rendering component (pipelines, renderpass, ..) are part of the VkvgDevice,
* their are shared among drawing contexts.
*
* Antialiasing level is configured when creating the device by selecting the sample count.
- * #vkvg_device_create will create a not antialiased by selecting VK_SAMPLE_COUNT_1_BIT as sample count.
- * To create antialiased rendering device, call #vkvg_device_create_multisample with VkSampleCountFlags
+ * @ref vkvg_device_create will create a non-antialiased dev by selecting VK_SAMPLE_COUNT_1_BIT as sample count.
+ * To create antialiased rendering device, call @ref vkvg_device_create_multisample with VkSampleCountFlags
* greater than one.
*
* vkvg use a single frame buffer format for now: VK_FORMAT_B8G8R8A8_UNORM.
/**
* @brief Create a new vkvg device.
*
+ * Create a new #VkvgDevice owning vulkan instance and device.
+ *
+ * On success, create a new vkvg device and set its reference count to 1.
+ * On error, query the device status by calling @ ref vkvg_device_status(). Error could be
+ * one of the following:
+ * - VKVG_STATUS_INVALID_FORMAT: the combination of image format and tiling is not supported
+ * - VKVG_STATUS_NULL_POINTER: vulkan function pointer fetching failed.
+ *
+ * @param samples The sample count that will be setup for the surfaces created by this device.
+ * @param deferredResolve If true, the final simple sampled image of the surface will only be resolved on demand
+ */
+vkvg_public
+VkvgDevice vkvg_device_create (VkSampleCountFlags samples, bool deferredResolve);
+/**
+ * @brief Create a new vkvg device from an existing vulkan logical device.
+ *
* Create a new #VkvgDevice connected to the vulkan context define by an instance,
- * a physical device, a logical device, a graphical queue family index and an index
+ * a physical device, a logical device, a graphical queue family index and an its index.
*
* On success, create a new vkvg device and set its reference count to 1.
* On error, query the device status by calling #vkvg_device_status(). Error could be
* @return The handle of the created vkvg device, or null if an error occured.
*/
vkvg_public
-VkvgDevice vkvg_device_create (VkInstance inst, VkPhysicalDevice phy, VkDevice vkdev, uint32_t qFamIdx, uint32_t qIndex);
+VkvgDevice vkvg_device_create_from_vk (VkInstance inst, VkPhysicalDevice phy, VkDevice vkdev, uint32_t qFamIdx, uint32_t qIndex);
/**
* @brief Create a new multisampled vkvg device.
*
* @return The handle of the created vkvg device, or null if an error occured.
*/
vkvg_public
-VkvgDevice vkvg_device_create_multisample (VkInstance inst, VkPhysicalDevice phy, VkDevice vkdev, uint32_t qFamIdx, uint32_t qIndex, VkSampleCountFlags samples, bool deferredResolve);
+VkvgDevice vkvg_device_create_from_vk_multisample (VkInstance inst, VkPhysicalDevice phy, VkDevice vkdev, uint32_t qFamIdx, uint32_t qIndex, VkSampleCountFlags samples, bool deferredResolve);
/**
* @brief Decrement the reference count of the device by 1. Release all it's ressources if count reach 0.
*
#include "vkh_phyinfo.h"
#include "vk_mem_alloc.h"
-VkvgDevice vkvg_device_create(VkInstance inst, VkPhysicalDevice phy, VkDevice vkdev, uint32_t qFamIdx, uint32_t qIndex)
+VkvgDevice vkvg_device_create(VkSampleCountFlags samples, bool deferredResolve) {
+ const char* enabledExts [10];
+ uint32_t enabledExtsCount = 0, phyCount = 0;
+#if defined(DEBUG) && defined (VKVG_DBG_UTILS)
+ enabledExts[enabledExtsCount++] = "VK_EXT_debug_utils";
+#endif
+
+ VkhApp app = vkh_app_create("vkvg", 0, NULL, enabledExtsCount, enabledExts);
+
+#if defined(DEBUG) && defined (VKVG_DBG_UTILS)
+ vkh_app_enable_debug_messenger(app
+ , VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT
+ , VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT
+ , NULL);
+#endif
+ VkhPhyInfo* phys = vkh_app_get_phyinfos (app, &phyCount, VK_NULL_HANDLE);
+ if (phyCount == 0) {
+ vkh_app_destroy (app);
+ return NULL;
+ }
+
+ VkhPhyInfo pi = 0;
+ if (!_try_get_phyinfo(phys, phyCount, VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, &pi))
+ if (!_try_get_phyinfo(phys, phyCount, VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, &pi))
+ pi = phys[0];
+
+ uint32_t qCount = 0;
+ float qPriorities[] = {0.0};
+ VkDeviceQueueCreateInfo pQueueInfos[] = { {0},{0},{0} };
+
+ if (vkh_phyinfo_create_queues (pi, pi->gQueue, 1, qPriorities, &pQueueInfos[qCount]))
+ qCount++;
+
+ VkPhysicalDeviceFeatures enabledFeatures = {
+ //.fillModeNonSolid = true,
+ };
+
+ enabledExtsCount=0;
+ //enabledExts[enabledExtsCount++] = "VK_KHR_swapchain";
+
+ VkDeviceCreateInfo device_info = { .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
+ .queueCreateInfoCount = qCount,
+ .pQueueCreateInfos = (VkDeviceQueueCreateInfo*)&pQueueInfos,
+ .enabledExtensionCount = enabledExtsCount,
+ .ppEnabledExtensionNames = enabledExts,
+ .pEnabledFeatures = &enabledFeatures};
+
+ VkhDevice vkhd = vkh_device_create(app, pi, &device_info);
+
+ VkvgDevice vkvgDev = vkvg_device_create_from_vk_multisample (
+ vkh_app_get_inst(app),
+ vkh_device_get_phy(vkhd),
+ vkh_device_get_vkdev(vkhd),
+ pi->gQueue, 0,
+ samples, deferredResolve);
+
+ vkvgDev->vkhDev = vkhd;
+
+ vkh_app_free_phyinfos (phyCount, phys);
+
+ return vkvgDev;
+}
+VkvgDevice vkvg_device_create_from_vk(VkInstance inst, VkPhysicalDevice phy, VkDevice vkdev, uint32_t qFamIdx, uint32_t qIndex)
{
- return vkvg_device_create_multisample (inst,phy,vkdev,qFamIdx,qIndex, VK_SAMPLE_COUNT_1_BIT, false);
+ return vkvg_device_create_from_vk_multisample (inst,phy,vkdev,qFamIdx,qIndex, VK_SAMPLE_COUNT_1_BIT, false);
}
-VkvgDevice vkvg_device_create_multisample(VkInstance inst, VkPhysicalDevice phy, VkDevice vkdev, uint32_t qFamIdx, uint32_t qIndex, VkSampleCountFlags samples, bool deferredResolve)
+VkvgDevice vkvg_device_create_from_vk_multisample(VkInstance inst, VkPhysicalDevice phy, VkDevice vkdev, uint32_t qFamIdx, uint32_t qIndex, VkSampleCountFlags samples, bool deferredResolve)
{
LOG(VKVG_LOG_INFO, "CREATE Device: qFam = %d; qIdx = %d\n", qFamIdx, qIndex);
MUTEX_DESTROY (&dev->gQMutex);
+ if (dev->vkhDev) {
+ VkhApp app = vkh_device_get_app (dev->vkhDev);
+ vkh_device_destroy (dev->vkhDev);
+ vkh_app_destroy (app);
+ }
+
free(dev);
}
PFN_vkCmdPushConstants CmdPushConstants;
+bool _try_get_phyinfo (VkhPhyInfo* phys, uint32_t phyCount, VkPhysicalDeviceType gpuType, VkhPhyInfo* phy) {
+ for (uint32_t i=0; i<phyCount; i++){
+ if (vkh_phyinfo_get_properties(phys[i]).deviceType == gpuType) {
+ *phy = phys[i];
+ return true;
+ }
+ }
+ return false;
+}
void _flush_all_contexes (VkvgDevice dev){
VkvgContext ctx = dev->lastCtx;
while (ctx != NULL){
int hdpi, /**< only used for FreeType fonts and svg loading */
vdpi;
+ VkhDevice vkhDev; /**< old VkhDev created during vulkan context creation by @ref vkvg_device_create. */
+
VkhImage emptyImg; /**< prevent unbound descriptor to trigger Validation error 61 */
VkSampleCountFlags samples; /**< samples count common to all surfaces */
bool deferredResolve; /**< if true, resolve only on context destruction and set as source */
VkvgContext lastCtx; /**< last element of double linked list of context, used to trigger font caching system update on all contexts*/
}vkvg_device;
+bool _try_get_phyinfo (VkhPhyInfo* phys, uint32_t phyCount, VkPhysicalDeviceType gpuType, VkhPhyInfo* phy);
bool _init_function_pointers (VkvgDevice dev);
void _create_empty_texture (VkvgDevice dev, VkFormat format, VkImageTiling tiling);
void _get_best_image_tiling (VkvgDevice dev, VkFormat format, VkImageTiling* pTiling);
bool deferredResolve = false;
- device = vkvg_device_create_multisample(vkh_app_get_inst(e->app), r->dev->phy, r->dev->dev, r->qFam, 0, samples, deferredResolve);
+ device = vkvg_device_create_from_vk_multisample(vkh_app_get_inst(e->app), r->dev->phy, r->dev->dev, r->qFam, 0, samples, deferredResolve);
surf = vkvg_surface_create(device, width, height);
vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), width, height);
VkhDevice dev = vkh_device_create(app, pi, &device_info);
- device = vkvg_device_create_multisample(vkh_app_get_inst(app), dev->phy, dev->dev, pi->gQueue, 0, samples, deferredResolve);
+ device = vkvg_device_create_from_vk_multisample(vkh_app_get_inst(app), dev->phy, dev->dev, pi->gQueue, 0, samples, deferredResolve);
//vkvg_device_set_dpy(device, 96, 96);
vkh_app_free_phyinfos (phyCount, phys);
bool deferredResolve = false;
- device = vkvg_device_create_multisample(vkh_app_get_inst(e->app), r->dev->phy, r->dev->dev, r->qFam, 0, samples, deferredResolve);
+ device = vkvg_device_create_from_vk_multisample(vkh_app_get_inst(e->app), r->dev->phy, r->dev->dev, r->qFam, 0, samples, deferredResolve);
vkvg_device_set_dpy(device, 96, 96);
--- /dev/null
+#include "vkvg.h"
+
+int main(int argc, char *argv[]) {
+ VkvgDevice dev = vkvg_device_create(VK_SAMPLE_COUNT_1_BIT, false);
+ VkvgSurface surf = vkvg_surface_create(dev, 512,512);
+ VkvgContext ctx = vkvg_create(surf);
+
+ vkvg_clear(ctx);
+ vkvg_rectangle(ctx, 10, 10, 250, 200);
+ vkvg_set_source_rgb(ctx, 1, 0, 0);
+ vkvg_fill(ctx);
+
+ vkvg_destroy(ctx);
+
+ vkvg_surface_write_to_png(surf, "offscreen.png");
+ vkvg_surface_destroy(surf);
+
+ vkvg_device_destroy(dev);
+ return 0;
+}
-Subproject commit 7dfff1a2e601e142583c122c9f716578d8e85039
+Subproject commit b15e2e52f6eb74e72f31391dbcf007a9e5ce3815