#define LOG_FULL 0xff
#ifdef DEBUG
-static uint8_t log_level = LOG_ERR;// LOG_INFO | LOG_DEBUG;
+static uint8_t log_level = LOG_ERR;// | LOG_INFO | LOG_DEBUG;
#define LOG(level,...) (log_level & level) ? fprintf (stdout, __VA_ARGS__):true;
#else
#define LOG
--- /dev/null
+/*
+ * Copyright (c) 2018 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
+ * Software, and to permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "cross_os.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+
+int directoryExists (const char* path) {
+#ifdef _WIN32
+ return getenv("HOME");
+#elif __APPLE__
+#elif __unix__
+ struct stat st = {0};
+ return stat(path, &st)+1;
+#endif
+ return -1;
+}
+const char* getUserDir () {
+#ifdef _WIN32
+ return getenv("HOME");
+#elif __APPLE__
+#elif __unix__
+ struct passwd *pw = getpwuid(getuid());
+ return pw->pw_dir;
+#endif
+ return -1;
+}
--- /dev/null
+/*
+ * Copyright (c) 2018 Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
+ * Software, and to permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef CROSS_OS_H
+#define CROSS_OS_H
+
+//cross platform os helpers
+#ifdef _WIN32
+#include "windows.h"
+#elif __APPLE__
+#elif __unix__
+#include <unistd.h>
+#include <sys/types.h>
+#include <pwd.h>
+#endif
+
+const char* getUserDir ();
+
+#endif // CROSS_OS_H
#endif
static VkClearValue clearValues[3] = {
- { {{0.0f, 0.0f, 0.0f, 1.0f}} },
- { {{1.0f, 0}} },
- { {{0.0f, 0.0f, 0.0f, 1.0f}} }
+ { 0.0f, 0.0f, 0.0f, 0.0f },
+ { 1.0f, 0 },
+ { 0.0f, 0.0f, 0.0f, 0.0f }
};
/**
*/
VkvgContext vkvg_create(VkvgSurface surf)
{
- LOG(LOG_INFO, "CREATE Context: surf = %lu\n", (ulong)surf);
-
VkvgDevice dev = surf->dev;
VkvgContext ctx = (vkvg_context*)calloc(1, sizeof(vkvg_context));
+ LOG(LOG_INFO, "CREATE Context: ctx = %lu; surf = %lu\n", (ulong)ctx, (ulong)surf);
+
if (ctx==NULL) {
dev->status = VKVG_STATUS_NO_MEMORY;
return NULL;
ctx->renderPassBeginInfo.renderArea.extent.width = ctx->pSurf->width;
ctx->renderPassBeginInfo.renderArea.extent.height = ctx->pSurf->height;
ctx->renderPassBeginInfo.pClearValues = clearValues;
- ctx->renderPassBeginInfo.renderPass = ctx->pSurf->dev->renderPass_ClearStencil;
+
+ if (ctx->pSurf->new)
+ ctx->renderPassBeginInfo.renderPass = ctx->pSurf->dev->renderPass_ClearAll;
+ else
+ ctx->renderPassBeginInfo.renderPass = ctx->pSurf->dev->renderPass_ClearStencil;
+
+ ctx->pSurf->new = false;
+
ctx->renderPassBeginInfo.clearValueCount = 3;
ctx->pPrev = surf->dev->lastCtx;
_flush_cmd_buff(ctx);
+ LOG(LOG_INFO, "DESTROY Context: ctx = %lu; surf = %lu\n", (ulong)ctx, (ulong)ctx->pSurf);
+
if (ctx->pattern)
vkvg_pattern_destroy (ctx->pattern);
return;
_finish_path(ctx);
+ LOG(LOG_INFO, "CLIP: ctx = %lu; path cpt = %d;\n", ctx, ctx->pathPtr / 2);
+
if (ctx->pointCount * 4 > ctx->sizeIndices - ctx->indCount)//flush if vk buff is full
vkvg_flush(ctx);
}*/
void _end_render_pass (VkvgContext ctx) {
- LOG(LOG_INFO, "FLUSH Context: ctx = %lu; vert cpt = %d; ind cpt = %d\n", ctx, ctx->vertCount -4, ctx->indCount - 6);
+ LOG(LOG_INFO, "END RENDER PASS: ctx = %lu; vert cpt = %d; ind cpt = %d\n", ctx, ctx->vertCount -4, ctx->indCount - 6);
_record_draw_cmd (ctx);
CmdEndRenderPass (ctx->cmd);
ctx->renderPassBeginInfo.renderPass = ctx->pSurf->dev->renderPass;
_create_pipeline_cache (dev);
_init_fonts_cache (dev);
if (dev->deferredResolve || dev->samples == VK_SAMPLE_COUNT_1_BIT){
- dev->renderPass = _setupRenderPassNoResolve (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD);
- dev->renderPass_ClearStencil = _setupRenderPassNoResolve (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_CLEAR);
+ dev->renderPass = _createRenderPassNoResolve (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD);
+ dev->renderPass_ClearStencil = _createRenderPassNoResolve (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_CLEAR);
+ dev->renderPass_ClearAll = _createRenderPassNoResolve (dev, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_CLEAR);
}else{
dev->renderPass = _createRenderPassMS (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD);
dev->renderPass_ClearStencil = _createRenderPassMS (dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_CLEAR);
+ dev->renderPass_ClearAll = _createRenderPassMS (dev, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_CLEAR);
}
_createDescriptorSetLayout (dev);
_setupPipelines (dev);
vkDestroyPipelineCache (dev->vkDev, dev->pipelineCache, NULL);
vkDestroyRenderPass (dev->vkDev, dev->renderPass, NULL);
vkDestroyRenderPass (dev->vkDev, dev->renderPass_ClearStencil, NULL);
+ vkDestroyRenderPass (dev->vkDev, dev->renderPass_ClearAll, NULL);
vkWaitForFences (dev->vkDev, 1, &dev->fence, VK_TRUE, UINT64_MAX);
VK_CHECK_RESULT(vkCreatePipelineCache(dev->vkDev, &pipelineCacheCreateInfo, NULL, &dev->pipelineCache));
}
-VkRenderPass _setupRenderPassNoResolve(VkvgDevice dev, VkAttachmentLoadOp loadOp, VkAttachmentLoadOp stencilLoadOp)
+VkRenderPass _createRenderPassNoResolve(VkvgDevice dev, VkAttachmentLoadOp loadOp, VkAttachmentLoadOp stencilLoadOp)
{
VkAttachmentDescription attColor = {
.format = FB_COLOR_FORMAT,
VkAttachmentDescription attColorResolve = {
.format = FB_COLOR_FORMAT,
.samples = VK_SAMPLE_COUNT_1_BIT,
- .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
- .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
+ .loadOp = loadOp,
+ .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
MUTEX gQMutex; /**< queue submission has to be externally syncronized */
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 */
+ VkRenderPass renderPass_ClearAll; /**< Vulkan render pass for new surface, clear all attacments*/
uint32_t references; /**< Reference count, prevent destroying device if still in use */
VkCommandPool cmdPool; /**< Global command pool for processing on surfaces without context */
void _check_image_format_properties (VkvgDevice dev);
void _create_pipeline_cache (VkvgDevice dev);
VkRenderPass _createRenderPassMS(VkvgDevice dev, VkAttachmentLoadOp loadOp, VkAttachmentLoadOp stencilLoadOp);
-VkRenderPass _setupRenderPassNoResolve(VkvgDevice dev, VkAttachmentLoadOp loadOp, VkAttachmentLoadOp stencilLoadOp);
+VkRenderPass _createRenderPassNoResolve(VkvgDevice dev, VkAttachmentLoadOp loadOp, VkAttachmentLoadOp stencilLoadOp);
void _setupPipelines (VkvgDevice dev);
void _createDescriptorSetLayout (VkvgDevice dev);
void _flush_all_contexes (VkvgDevice dev);
surf->dev = dev;
surf->width = width;
surf->height = height;
+ surf->new = true;//used to clear all attacments on first render pass
_init_surface (surf);
VkhImage imgMS;
VkhImage stencil;
uint32_t references;
+ bool new;
}vkvg_surface;
void _clear_surface (VkvgSurface surf, VkImageAspectFlags aspect);
--- /dev/null
+#include "test.h"
+
+void test(){
+ VkvgContext ctx = vkvg_create(surf);
+
+ vkvg_destroy(ctx);
+}
+
+int main(int argc, char *argv[]) {
+
+ perform_test (test, 600, 800);
+
+ return 0;
+}
(float)rand()/RAND_MAX
);
}
+static vk_engine_t* e;
+
+void init_test (uint width, uint height){
+ e = vkengine_create (VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_PRESENT_MODE_MAILBOX_KHR, width, height);
+ VkhPresenter r = e->renderer;
+ vkengine_set_key_callback (e, key_callback);
+ vkengine_set_mouse_but_callback(e, mouse_button_callback);
+ vkengine_set_cursor_pos_callback(e, mouse_move_callback);
+ vkengine_set_scroll_callback(e, scroll_callback);
+
+ bool deferredResolve = false;
+
+ device = vkvg_device_create_multisample(vkh_app_get_inst(e->app), r->dev->phy, r->dev->dev, r->qFam, 0, VK_SAMPLE_COUNT_1_BIT, deferredResolve);
+
+ vkvg_device_set_dpy(device, 96, 96);
+
+ surf = vkvg_surface_create(device, width, height);
+
+ vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), width, height);
+}
+void run_test_func (void(*testfunc)(void),uint width, uint height) {
+ bool deferredResolve = false;
+ VkhPresenter r = e->renderer;
+
+ struct timeval before , after;
+ double frameTime = 0, frameTimeAccum = 0, frameCount = 0;
+
+ while (!vkengine_should_close (e)) {
+ glfwPollEvents();
+
+ gettimeofday(&before , NULL);
+
+ testfunc();
+
+ if (deferredResolve)
+ vkvg_multisample_surface_resolve(surf);
+ if (!vkh_presenter_draw (r))
+ vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), width, height);
+
+ vkDeviceWaitIdle(e->dev->dev);
+
+ gettimeofday(&after , NULL);
+
+ frameTimeAccum += time_diff(before , after);
+ frameCount++;
+ }
+
+ frameTime = frameTimeAccum / frameCount;
+ printf ("frame (µs): %.0lf\nfps: %lf\n", frameTime, floor(1000000 / frameTime));
+
+}
+void clear_test () {
+ vkDeviceWaitIdle(e->dev->dev);
+
+ vkvg_surface_destroy (surf);
+ vkvg_device_destroy (device);
+
+ vkengine_destroy (e);
+}
void perform_test (void(*testfunc)(void),uint width, uint height) {
//dumpLayerExts();
- vk_engine_t* e = vkengine_create (VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_PRESENT_MODE_MAILBOX_KHR, width, height);
+ e = vkengine_create (VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_PRESENT_MODE_MAILBOX_KHR, width, height);
VkhPresenter r = e->renderer;
vkengine_set_key_callback (e, key_callback);
vkengine_set_mouse_but_callback(e, mouse_button_callback);
extern VkvgDevice device;
extern VkvgSurface surf;
+//run test in one step
void perform_test (void(*testfunc)(void),uint width, uint height);
void randomize_color (VkvgContext ctx);
+
+//run test in 3 step: init, run, clear.
+void init_test (uint width, uint height);
+void run_test_func (void(*testfunc)(void),uint width, uint height);
+void clear_test ();
#include "test.h"
+static VkvgSurface surf2;
+
void test(){
- VkvgSurface surf2 = vkvg_surface_create (device,400,400);;
- VkvgContext ctx = vkvg_create (surf2);
+ VkvgContext ctx = vkvg_create (surf);
- vkvg_set_source_rgba(ctx,1.0,0.,0.,1.0);
+ vkvg_set_source_surface(ctx,surf2,0,0);
vkvg_paint (ctx);
-
vkvg_destroy (ctx);
- ctx = vkvg_create (surf);
- vkvg_set_source_rgba(ctx,0.1,0.1,0.3,1.0);
- vkvg_paint (ctx);
+ return;
+
+ //vkvg_set_source_rgba(ctx,0.1,0.1,0.3,1.0);
+ //vkvg_paint (ctx);
- //vkvg_set_source_surface(ctx,surf2,0,0);
+ for (int i=0; i<10; i++) {
+ vkvg_translate(ctx,50,50);
+
+ /*vkvg_save(ctx);
+
+ vkvg_rectangle(ctx,0,0,200,200);
+ vkvg_clip_preserve(ctx);
+ vkvg_set_operator(ctx,VKVG_OPERATOR_CLEAR);
+ vkvg_fill(ctx);
+ vkvg_set_operator(ctx,VKVG_OPERATOR_OVER);*/
+
+ vkvg_set_source_rgba(ctx,0.0,0.0,0.0,0.3f);
+ vkvg_move_to(ctx,0,0);
+ vkvg_line_to(ctx,0,200);
+ vkvg_set_line_width(ctx,10);
+ vkvg_stroke(ctx);
+ vkvg_set_source_surface(ctx,surf2,0,0);
+ vkvg_paint (ctx);
+
+ //vkvg_restore(ctx);
+ }
//VkvgPattern pat = vkvg_get_source (ctx);
- VkvgPattern pat = vkvg_pattern_create_for_surface(surf2);
+ /*VkvgPattern pat = vkvg_pattern_create_for_surface(surf2);
vkvg_pattern_set_extend (pat,VKVG_EXTEND_REFLECT);
- vkvg_set_source(ctx,pat);
- //vkvg_paint (ctx);
+ vkvg_set_source(ctx,pat);*/
//vkvg_set_source_rgba(ctx,0,1,0,1.0);
- vkvg_rectangle(ctx,100,100,200,200);
- vkvg_fill(ctx);
+ //vkvg_rectangle(ctx,100,100,200,200);
+ //vkvg_fill(ctx);
vkvg_destroy (ctx);
- vkvg_surface_destroy (surf2);
- vkvg_pattern_destroy (pat);
+
+ //vkvg_pattern_destroy (pat);
}
int main(int argc, char *argv[]) {
- perform_test (test, 1024, 768);
+ init_test(1024, 768);
+
+ surf2 = vkvg_surface_create (device,400,400);
+
+ VkvgContext ctx = vkvg_create (surf2);
+
+ vkvg_set_source_rgba(ctx,1.0,0.,0.,0.2f);
+ vkvg_paint (ctx);
+ vkvg_set_source_rgba(ctx,1.0,1.0,0.,0.5f);
+ vkvg_move_to(ctx,10,10);
+ vkvg_line_to(ctx,200,200);
+ vkvg_set_line_width(ctx,10);
+ vkvg_stroke(ctx);
+ vkvg_set_source_rgba(ctx,1.0,1.0,1.0,0.6f);
+ vkvg_rectangle(ctx,0,0,400,400);
+ vkvg_stroke(ctx);
+
+ vkvg_destroy (ctx);
+
+ run_test_func(test, 1024, 768);
+
+ vkvg_surface_destroy (surf2);
+ clear_test();
return 0;
}