#ifdef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE
VkvgSurface surf = ctx->pSurf;
VkvgDevice dev = surf->dev;
- vkh_timeline_wait ((VkhDevice)dev, surf->timeline, surf->timelineStep);
+ //vkh_timeline_wait ((VkhDevice)dev, surf->timeline, ct->timelineStep);
LOCK_SURFACE(surf)
LOCK_DEVICE
vkh_cmd_submit_timelined (dev->gQueue, &ctx->cmd, surf->timeline, surf->timelineStep, surf->timelineStep+1);
if (!_wait_flush_fence (ctx))
return false;
- _device_reset_fence(ctx->dev, ctx->flushFence);
+ ResetFences (ctx->dev->vkDev, 1, &ctx->flushFence);
_device_submit_cmd (ctx->dev, &ctx->cmd, ctx->flushFence);
#endif
VkDevice dev = ctx->dev->vkDev;
#ifndef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE
- _device_destroy_fence (ctx->dev, ctx->flushFence);
+ vkDestroyFence (dev, ctx->flushFence, NULL);
#endif
vkFreeCommandBuffers(dev, ctx->cmdPool, 2, ctx->cmdBuffers);
vkWaitForFences (dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX);
vkDestroyFence (dev->vkDev, dev->fence,NULL);
- //vkFreeCommandBuffers (dev->vkDev, dev->cmdPool, 1, &dev->cmd);
+ vkFreeCommandBuffers (dev->vkDev, dev->cmdPool, 1, &dev->cmd);
vkDestroyCommandPool (dev->vkDev, dev->cmdPool, NULL);
vkh_queue_destroy(dev->gQueue);
}
void _device_wait_and_reset_device_fence (VkvgDevice dev) {
vkWaitForFences (dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX);
- _device_reset_fence(dev, dev->fence);
+ ResetFences (dev->vkDev, 1, &dev->fence);
}
-void _device_destroy_fence (VkvgDevice dev, VkFence fence) {
- LOCK_DEVICE
-
- if (dev->gQLastFence == fence)
- dev->gQLastFence = VK_NULL_HANDLE;
-
- vkDestroyFence (dev->vkDev, fence, NULL);
-
- UNLOCK_DEVICE
-}
-void _device_reset_fence (VkvgDevice dev, VkFence fence){
- LOCK_DEVICE
-
- if (dev->gQLastFence == fence)
- dev->gQLastFence = VK_NULL_HANDLE;
-
- ResetFences (dev->vkDev, 1, &fence);
-
- UNLOCK_DEVICE
-}
bool _device_try_get_cached_context (VkvgDevice dev, VkvgContext* pCtx) {
LOCK_DEVICE
LOCK_DEVICE
-#ifndef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE
- if (dev->gQLastFence == ctx->flushFence)
- dev->gQLastFence = VK_NULL_HANDLE;
-#endif
dev->cachedContext[dev->cachedContextCount++] = ctx;
ctx->references++;
}
void _device_submit_cmd (VkvgDevice dev, VkCommandBuffer* cmd, VkFence fence) {
LOCK_DEVICE
- if (dev->gQLastFence != VK_NULL_HANDLE)
- WaitForFences (dev->vkDev, 1, &dev->gQLastFence, VK_TRUE, VKVG_FENCE_TIMEOUT);
vkh_cmd_submit (dev->gQueue, cmd, fence);
- dev->gQLastFence = fence;
UNLOCK_DEVICE
}
mtx_t mutex; /**< protect device access (queue, cahes, ...)from ctxs in separate threads */
bool threadAware; /**< if true, mutex is created and guard device queue and caches access */
VkhQueue gQueue; /**< Vulkan Queue with Graphic flag */
- VkFence gQLastFence;
VkRenderPass renderPass; /**< Vulkan render pass, common for all surfaces */
VkRenderPass renderPass_ClearStencil;/**< Vulkan render pass for first draw with context, stencil has to be cleared */
void _device_wait_and_reset_device_fence(VkvgDevice dev);
void _device_submit_cmd (VkvgDevice dev, VkCommandBuffer* cmd, VkFence fence);
-void _device_destroy_fence (VkvgDevice dev, VkFence fence);
-void _device_reset_fence (VkvgDevice dev, VkFence fence);
bool _device_try_get_cached_context (VkvgDevice dev, VkvgContext* pCtx);
void _device_store_context (VkvgContext ctx);
#endif
_font_cache_t* cache = dev->fontCache;
vkWaitForFences (dev->vkDev, 1, &cache->uploadFence, VK_TRUE, UINT64_MAX);
- _device_reset_fence (dev, cache->uploadFence);
+ ResetFences (dev->vkDev, 1, &cache->uploadFence);
vkResetCommandBuffer(cache->cmd, 0);
LOG(VKVG_LOG_INFO, "_flush_chars_to_tex pen(%d, %d)\n",f->curLine.penX, f->curLine.penY);
vkWaitForFences (dev->vkDev,1,&cache->uploadFence,VK_TRUE,UINT64_MAX);
- _device_reset_fence (dev, cache->uploadFence);
+ ResetFences (dev->vkDev, 1, &cache->uploadFence);
+
vkResetCommandBuffer(cache->cmd,0);
memcpy(cache->buff.allocInfo.pMappedData, cache->hostBuff, (uint64_t)f->curLine.height * FONT_PAGE_SIZE * cache->texPixelSize);
#include "vkh_image.h"
#define max(x,y)
+void _transition_surf_images (VkvgSurface surf) {
+ LOCK_SURFACE(surf)
+ VkvgDevice dev = surf->dev;
+
+ //_surface_wait_cmd (surf);
+
+ vkh_cmd_begin (surf->cmd,VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
+ VkhImage imgMs = surf->imgMS;
+ if (imgMs != NULL)
+ vkh_image_set_layout(surf->cmd, imgMs, VK_IMAGE_ASPECT_COLOR_BIT,
+ VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
+
+ vkh_image_set_layout(surf->cmd, surf->img, VK_IMAGE_ASPECT_COLOR_BIT,
+ VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
+ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
+ vkh_image_set_layout (surf->cmd, surf->stencil, VK_IMAGE_ASPECT_STENCIL_BIT,
+ VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
+ VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
+ vkh_cmd_end (surf->cmd);
+
+ _surface_submit_cmd (surf);
+
+ UNLOCK_SURFACE(surf)
+}
void vkvg_surface_clear (VkvgSurface surf) {
if (surf->status)
return;
_create_surface_images (surf);
+ _transition_surf_images (surf);
+
surf->status = VKVG_STATUS_SUCCESS;
vkvg_device_reference (surf->dev);
return surf;
_create_surface_secondary_images (surf);
_create_framebuffer (surf);
- _clear_surface (surf, VK_IMAGE_ASPECT_STENCIL_BIT);
+
+ _transition_surf_images (surf);
+ //_clear_surface (surf, VK_IMAGE_ASPECT_STENCIL_BIT);
surf->status = VKVG_STATUS_SUCCESS;
vkvg_device_reference (surf->dev);
memcpy (buff.allocInfo.pMappedData, img, imgSize);
- VkCommandBuffer cmd = dev->cmd;
-
- _device_wait_and_reset_device_fence (dev);
+ VkCommandBuffer cmd = surf->cmd;
vkh_cmd_begin (cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
vkh_image_set_layout (cmd, stagImg, VK_IMAGE_ASPECT_COLOR_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
vkh_cmd_end (cmd);
- _device_submit_cmd (dev, &cmd, dev->fence);
- //don't reset fence after completion as this is the last cmd. (signaled idle fence)
- vkWaitForFences (dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX);
+ _surface_submit_cmd (surf);
vkvg_buffer_destroy (&buff);
vkh_image_destroy (stagImg);
}
UNLOCK_SURFACE(surf)
+ vkDestroyCommandPool(surf->dev->vkDev, surf->cmdPool, NULL);
vkDestroyFramebuffer(surf->dev->vkDev, surf->fb, NULL);
if (!surf->img->imported)
#if VKVG_ENABLE_VK_TIMELINE_SEMAPHORE
vkDestroySemaphore (surf->dev->vkDev, surf->timeline, NULL);
+#else
+ vkDestroyFence (surf->dev->vkDev, surf->flushFence, NULL);
#endif
vkvg_device_destroy (surf->dev);
VMA_MEMORY_USAGE_GPU_ONLY,
VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT);
- VkCommandBuffer cmd = dev->cmd;
- _device_wait_and_reset_device_fence (dev);
-
+ VkCommandBuffer cmd = surf->cmd;
vkh_cmd_begin (cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
vkh_image_set_layout (cmd, stagImg, VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
vkh_image_get_vkimage (stagImg), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit, VK_FILTER_NEAREST);
vkh_cmd_end (cmd);
- _device_submit_cmd (dev, &cmd, dev->fence);
+
+ _surface_submit_cmd (surf);
VkhImage stagImgLinear = stagImg;
.dstOffset = {0},
.extent = {(int32_t)surf->width, (int32_t)surf->height, 1}
};
- _device_wait_and_reset_device_fence (dev);
vkh_cmd_begin (cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
vkh_image_set_layout (cmd, stagImgLinear, VK_IMAGE_ASPECT_COLOR_BIT,
vkh_image_get_vkimage (stagImgLinear), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &cpy);
vkh_cmd_end (cmd);
- _device_submit_cmd (dev, &cmd, dev->fence);
- vkWaitForFences (dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX);
+ _surface_submit_cmd (surf);
+
vkh_image_destroy (stagImg);
- } else
- vkWaitForFences (dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX);
+ }
void* img = vkh_image_map (stagImgLinear);
VMA_MEMORY_USAGE_GPU_TO_CPU,
VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT);
- VkCommandBuffer cmd = dev->cmd;
- _device_wait_and_reset_device_fence (dev);
+ VkCommandBuffer cmd = surf->cmd;
vkh_cmd_begin (cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
vkh_image_set_layout (cmd, stagImg, VK_IMAGE_ASPECT_COLOR_BIT,
vkh_image_get_vkimage (stagImg), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit, VK_FILTER_NEAREST);
vkh_cmd_end (cmd);
- _device_submit_cmd (dev, &cmd, dev->fence);
- vkWaitForFences (dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX);
+
+ _surface_submit_cmd (surf);
uint64_t stride = vkh_image_get_stride(stagImg);
uint32_t dest_stride = surf->width * 4;
* THE SOFTWARE.
*/
-#include "vkvg_surface_internal.h"
#include "vkvg_device_internal.h"
+#include "vkvg_surface_internal.h"
#include "vkh_image.h"
+#include "vkh_queue.h"
void _explicit_ms_resolve (VkvgSurface surf){
- VkvgDevice dev = surf->dev;
- VkCommandBuffer cmd = dev->cmd;
-
- _device_wait_and_reset_device_fence (dev);
+ VkCommandBuffer cmd = surf->cmd;
vkh_cmd_begin (cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
vkh_image_set_layout (cmd, surf->imgMS, VK_IMAGE_ASPECT_COLOR_BIT,
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
vkh_cmd_end (cmd);
- _device_submit_cmd (dev, &cmd, dev->fence);
+ _surface_submit_cmd (surf);
}
void _clear_surface (VkvgSurface surf, VkImageAspectFlags aspect)
{
- VkvgDevice dev = surf->dev;
- VkCommandBuffer cmd = dev->cmd;
-
- _device_wait_and_reset_device_fence (dev);
+ VkCommandBuffer cmd = surf->cmd;
vkh_cmd_begin (cmd, VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
}
vkh_cmd_end (cmd);
- _device_submit_cmd (dev, &cmd, dev->fence);
+ _surface_submit_cmd (surf);
}
void _create_surface_main_image (VkvgSurface surf){
surf->format = format;
if (dev->threadAware)
mtx_init (&surf->mutex, mtx_plain);
+ surf->cmdPool = vkh_cmd_pool_create ((VkhDevice)dev, dev->gQueue->familyIndex, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT);
+ vkh_cmd_buffs_create((VkhDevice)dev, surf->cmdPool,VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1, &surf->cmd);
#if VKVG_ENABLE_VK_TIMELINE_SEMAPHORE
surf->timeline = vkh_timeline_create ((VkhDevice)dev, 0);
+#else
+ surf->flushFence = vkh_fence_create ((VkhDevice)dev);
+#endif
+
+#if defined(DEBUG) && defined(VKVG_DBG_UTILS)
+ vkh_device_set_object_name((VkhDevice)dev, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)surf->cmd, "vkvgSurfCmd");
#endif
+
return surf;
}
+//if fence sync, surf mutex must be locked.
+/*bool _surface_wait_cmd (VkvgSurface surf) {
+ LOG(VKVG_LOG_INFO, "SURF: _surface__wait_flush_fence\n");
+#ifdef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE
+ if (vkh_timeline_wait ((VkhDevice)surf->dev, surf->timeline, surf->timelineStep) == VK_SUCCESS)
+ return true;
+#else
+ if (WaitForFences (surf->dev->vkDev, 1, &surf->flushFence, VK_TRUE, VKVG_FENCE_TIMEOUT) == VK_SUCCESS) {
+ ResetFences (surf->dev->vkDev, 1, &surf->flushFence);
+ return true;
+ }
+#endif
+ LOG(VKVG_LOG_DEBUG, "CTX: _wait_flush_fence timeout\n");
+ surf->status = VKVG_STATUS_TIMEOUT;
+ return false;
+}*/
+//surface mutex must be locked to call this method, locking to guard also the surf->cmd local buffer usage.
+void _surface_submit_cmd (VkvgSurface surf) {
+ VkvgDevice dev = surf->dev;
+#ifdef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE
+ LOCK_DEVICE
+ vkh_cmd_submit_timelined (dev->gQueue, &surf->cmd, surf->timeline, surf->timelineStep, surf->timelineStep+1);
+ surf->timelineStep++;
+ UNLOCK_DEVICE
+ vkh_timeline_wait ((VkhDevice)dev, surf->timeline, surf->timelineStep);
+#else
+ LOCK_DEVICE
+ vkh_cmd_submit (surf->dev->gQueue, &surf->cmd, surf->flushFence);
+ UNLOCK_DEVICE
+ WaitForFences (surf->dev->vkDev, 1, &surf->flushFence, VK_TRUE, VKVG_FENCE_TIMEOUT);
+ ResetFences (surf->dev->vkDev, 1, &surf->flushFence);
+#endif
+}
VkhImage img;
VkhImage imgMS;
VkhImage stencil;
+ VkCommandPool cmdPool; //local pools ensure thread safety
+ VkCommandBuffer cmd; //surface local command buffer.
bool newSurf;
mtx_t mutex;
#ifdef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE
VkSemaphore timeline; /**< Timeline semaphore */
uint64_t timelineStep;
+#else
+ VkFence flushFence; //unsignaled idle.
#endif
+
}vkvg_surface;
#define LOCK_SURFACE(surf) \
void _create_framebuffer (VkvgSurface surf);
void _create_surface_images (VkvgSurface surf);
VkvgSurface _create_surface (VkvgDevice dev, VkFormat format);
+
+void _surface_submit_cmd (VkvgSurface surf);
+//bool _surface_wait_cmd (VkvgSurface surf);
#endif