diff options
| author | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2026-10-16 11:52:13 +0200 |
|---|---|---|
| committer | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2026-10-16 11:52:13 +0200 |
| commit | d65ceda25ffe435114f0416d6bb1ad9164932907 (patch) | |
| tree | cd7f802aa799abc12a1ede74a8baf93e1d30dde5 | |
| parent | 0ea75d9f9a84a9fdcb8375512165728aa2820ad7 (diff) | |
move pipeline,renderpass,dpy,sample count to surf
| -rw-r--r-- | gunit_tests/drawTestBase.cpp | 2 | ||||
| -rw-r--r-- | gunit_tests/textDraw.cpp | 10 | ||||
| -rw-r--r-- | include/vkvg.h | 46 | ||||
| -rw-r--r-- | samples/VkvgTest.cpp | 2 | ||||
| -rw-r--r-- | src/svg/svg-parse.c | 4 | ||||
| -rw-r--r-- | src/vkvg_context.c | 22 | ||||
| -rw-r--r-- | src/vkvg_context_internal.c | 12 | ||||
| -rw-r--r-- | src/vkvg_device.c | 65 | ||||
| -rw-r--r-- | src/vkvg_device_internal.c | 328 | ||||
| -rw-r--r-- | src/vkvg_device_internal.h | 16 | ||||
| -rw-r--r-- | src/vkvg_fonts.c | 21 | ||||
| -rw-r--r-- | src/vkvg_surface.c | 31 | ||||
| -rw-r--r-- | src/vkvg_surface_internal.c | 378 | ||||
| -rw-r--r-- | src/vkvg_surface_internal.h | 12 | ||||
| -rw-r--r-- | tests/common/test.c | 4 | ||||
| -rw-r--r-- | tests/fonts/allfont.c | 6 | ||||
| -rw-r--r-- | tests/fonts/fontquery.c | 4 | ||||
| -rw-r--r-- | tests/text.c | 10 |
18 files changed, 488 insertions, 485 deletions
diff --git a/gunit_tests/drawTestBase.cpp b/gunit_tests/drawTestBase.cpp index 9a92414..a4bdc20 100644 --- a/gunit_tests/drawTestBase.cpp +++ b/gunit_tests/drawTestBase.cpp @@ -23,6 +23,8 @@ DrawTestBase::DrawTestBase() { vkvg_device_create_info_t info{}; info.samples = VK_SAMPLE_COUNT_4_BIT; + fs::path fontDir = fs::path(GTEST_DATA_ROOT) / "fonts"; + info.fontsDirectories = fontDir.c_str(); dev = vkvg_device_create(&info); } diff --git a/gunit_tests/textDraw.cpp b/gunit_tests/textDraw.cpp index 25b43a9..d543ed7 100644 --- a/gunit_tests/textDraw.cpp +++ b/gunit_tests/textDraw.cpp @@ -14,15 +14,15 @@ class TextDrawTest : public DrawTestBase { } }; TEST_F(TextDrawTest, References) { - VkvgFont font = vkvg_font_create(dev, "sans", 12); + VkvgFont font = vkvg_font_create(surf, "sans", 12); EXPECT_EQ(VKVG_STATUS_SUCCESS, vkvg_font_status(font)); vkvg_font_destroy(font); - font = vkvg_font_create(dev, "Sans", 12); + font = vkvg_font_create(surf, "Sans", 12); EXPECT_EQ(VKVG_STATUS_SUCCESS, vkvg_font_status(font)); vkvg_font_destroy(font); - font = vkvg_font_create(dev, "noto sans jp", 12); + font = vkvg_font_create(surf, "noto sans jp", 12); EXPECT_EQ(VKVG_STATUS_SUCCESS, vkvg_font_status(font)); vkvg_font_destroy(font); @@ -55,7 +55,7 @@ TEST_F(TextDrawTest, ShowText) { VkvgContext ctx = vkvg_create(surf); vkvg_paint(ctx); - VkvgFont font = vkvg_font_create(dev, "sans", 30); + VkvgFont font = vkvg_font_create(surf, "sans", 30); vkvg_set_font(ctx, font); vkvg_font_extents_t fe = {0}; vkvg_font_extents(ctx, &fe); @@ -67,7 +67,7 @@ TEST_F(TextDrawTest, ShowText) { vkvg_font_destroy(font); - font = vkvg_font_create(dev, "noto sans jp", 30); + font = vkvg_font_create(surf, "noto sans jp", 30); vkvg_set_font(ctx, font); vkvg_move_to(ctx, 40, penY); vkvg_show_text(ctx, "Galvanized by the quartz, The white rabbit just jumped on the red fox for the sake of the crows"); diff --git a/include/vkvg.h b/include/vkvg.h index c457060..2378bbc 100644 --- a/include/vkvg.h +++ b/include/vkvg.h @@ -333,21 +333,21 @@ typedef struct _vkvg_font_t* VkvgFont; * If fontconfig is enable, query strings with be parsed with fontconfig textural representation engine: * <families>-<point sizes>:<name1>=<values1>:<name2>=<values2>... * - * @param dev Each font instance will be bound to a @ref VkvgDevice which holds the font cache. + * @param surf Each font instance will be bound to a @ref VkvgDevice which holds the font cache. * @param queryString * @param pointSize The font size in point unit, 1/72 of an inch. * @return A new VkvgFont or null if an error occured. */ -vkvg_public VkvgFont vkvg_font_create (VkvgDevice dev, const char* queryString, float pointSize); +vkvg_public VkvgFont vkvg_font_create (VkvgSurface surf, const char* queryString, float pointSize); /** * @brief Create a new @ref VkvgFont from the provided font file, face index and size. - * @param dev VkvgDevice holding the font cache. + * @param surf VkvgDevice holding the font cache. * @param fontFilePath a valid font file path. * @param faceIndex Usually 0, except for variable fonts or font file with multiple faces. * @param pointSize The font size in point unit, 1/72 of an inch. * @return */ -vkvg_public VkvgFont vkvg_font_create_from_file (VkvgDevice dev, const char* fontFilePath, int faceIndex, float pointSize); +vkvg_public VkvgFont vkvg_font_create_from_file (VkvgSurface surf, const char* fontFilePath, int faceIndex, float pointSize); /** * @brief Get underlying font face object pointer, if freetype is enable, the FT_Face will be returned. * @param font a valid VkvgFont. @@ -715,25 +715,6 @@ vkvg_public VkvgDevice vkvg_device_reference(VkvgDevice dev); * @return The reference count on this device. */ vkvg_public uint32_t vkvg_device_get_reference_count(VkvgDevice dev); -/** - * @brief Set the screen dot per inch for this device. - * - * Set the current values for horizontal and vertical dot per inch of the screen for this device. - * @param dev The vkvg device to set the dpy for. - * @param hdpy Horizontal dot per inch. - * @param vdpy Vertical dot per inch. - */ -vkvg_public void vkvg_device_set_dpy(VkvgDevice dev, int hdpy, int vdpy); -/** - * @brief Get the current dpy values. - * - * Get the current values for horizontal and vertical dot per inch of the screen for this device. - * The default values for horizontal and vertical dpy on device creation is 96. - * @param dev The vkvg device to get the dpy configuration for. - * @param hdpy The current horizontal dot per inch. - * @param vdpy The current vertical dot per inch. - */ -vkvg_public void vkvg_device_get_dpy(VkvgDevice dev, int* hdpy, int* vdpy); /** * @brief query required instance extensions for vkvg. @@ -871,6 +852,25 @@ vkvg_public uint32_t vkvg_surface_get_width(VkvgSurface surf); */ vkvg_public uint32_t vkvg_surface_get_height(VkvgSurface surf); /** + * @brief Set the screen dot per inch for this surface. + * + * Set the current values for horizontal and vertical dot per inch of the screen for this device. + * @param surf The vkvg surface to set the dpy for. + * @param hdpy Horizontal dot per inch. + * @param vdpy Vertical dot per inch. + */ +vkvg_public void vkvg_surface_set_dpy(VkvgSurface surf, int hdpy, int vdpy); +/** + * @brief Get the current dpy values. + * + * Get the current values for horizontal and vertical dot per inch of the screen for this surface. + * The default values for horizontal and vertical dpy on device creation is 72. + * @param surf The vkvg surface to get the dpy configuration for. + * @param hdpy The current horizontal dot per inch. + * @param vdpy The current vertical dot per inch. + */ +vkvg_public void vkvg_surface_get_dpy(VkvgSurface surf, int* hdpy, int* vdpy); +/** * @brief Write surface content to a png file on disk. * @param surf The surface to save on disk. * @param path The png file path. diff --git a/samples/VkvgTest.cpp b/samples/VkvgTest.cpp index 6f5be46..24285d8 100644 --- a/samples/VkvgTest.cpp +++ b/samples/VkvgTest.cpp @@ -46,7 +46,7 @@ void VkvgTest::initTest(SampleApp* app) { device = vkvg_device_create(&info); surf = vkvg_surface_create(device, app->width, app->height); - vkvg_device_set_dpy(device, 96, 96); + vkvg_surface_set_dpy(surf, 96, 96); vkh_presenter_build_blit_cmd(app->renderer, vkvg_surface_get_vk_image(surf), app->width, app->height); diff --git a/src/svg/svg-parse.c b/src/svg/svg-parse.c index f4de1a0..3a56e5d 100644 --- a/src/svg/svg-parse.c +++ b/src/svg/svg-parse.c @@ -1415,7 +1415,7 @@ void parse_font_size(svg_context *const svg, SvgPresentationAttributes *attribs) attribs->font_size_pt *= lop.number * 0.01f; } else if (lop.units == svg_unit_px) { int hdpy, vdpy; - vkvg_device_get_dpy(svg->dev, &hdpy, &vdpy); + vkvg_surface_get_dpy(svg->surf, &hdpy, &vdpy); attribs->font_size_pt = lop.number * (72.f / (float)vdpy); } else if (lop.units == svg_unit_em) { attribs->font_size_pt *= lop.number; @@ -1570,7 +1570,7 @@ void process_element(svg_context *const svg, SvgPresentationAttributes *const at if (attribs->font_family_len > 0) { char fam[1024]; sprintf(fam, "%.*s", attribs->font_family_len, attribs->font_family); - font = vkvg_font_create(svg->dev, fam, attribs->font_size_pt); + font = vkvg_font_create(svg->surf, fam, attribs->font_size_pt); vkvg_set_font(svg->ctx, font); vkvg_font_destroy(font); } diff --git a/src/vkvg_context.c b/src/vkvg_context.c index bc0e646..e1c8fee 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -60,17 +60,17 @@ void _init_ctx(VkvgContext ctx) { LOCK_SURFACE(ctx->pSurf) if (ctx->pSurf->newSurf) { - ctx->renderPassBeginInfo.renderPass = ctx->dev->renderPass_ClearAll; + ctx->renderPassBeginInfo.renderPass = ctx->pSurf->renderPass_ClearAll; ctx->pSurf->newSurf = false; } else { - ctx->renderPassBeginInfo.renderPass = ctx->dev->renderPass_ClearStencil; + ctx->renderPassBeginInfo.renderPass = ctx->pSurf->renderPass_ClearStencil; } UNLOCK_SURFACE(ctx->pSurf); vkvg_surface_reference(ctx->pSurf); - ctx->renderPassBeginInfo.clearValueCount = ctx->dev->samples == VK_SAMPLE_COUNT_1_BIT ? 2 : 3; + ctx->renderPassBeginInfo.clearValueCount = ctx->pSurf->samples == VK_SAMPLE_COUNT_1_BIT ? 2 : 3; #ifdef VKVG_ENABLE_VK_TIMELINE_SEMAPHORE ctx->timelineStep = 0; @@ -745,7 +745,7 @@ void _reset_clip(VkvgContext ctx) { if (!ctx->cmdStarted) { // if command buffer is not already started and in a renderpass, we use the renderpass // with the loadop clear for stencil - ctx->renderPassBeginInfo.renderPass = ctx->dev->renderPass_ClearStencil; + ctx->renderPassBeginInfo.renderPass = ctx->pSurf->renderPass_ClearStencil; // force run of one renderpass (even empty) to perform clear load op _start_cmd_for_render_pass(ctx); return; @@ -781,7 +781,7 @@ void vkvg_clear(VkvgContext ctx) { _emit_draw_cmd_undrawn_vertices(ctx); if (!ctx->cmdStarted) { - ctx->renderPassBeginInfo.renderPass = ctx->dev->renderPass_ClearAll; + ctx->renderPassBeginInfo.renderPass = ctx->pSurf->renderPass_ClearAll; _start_cmd_for_render_pass(ctx); return; } @@ -806,9 +806,9 @@ void _clip_preserve(VkvgContext ctx) { if (ctx->curFillRule == VKVG_FILL_RULE_EVEN_ODD) { _poly_fill(ctx, NULL); - CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelineClipping); + CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->pipelineClipping); } else { - CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelineClipping); + CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->pipelineClipping); CmdSetStencilReference(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_FILL_BIT); CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); CmdSetStencilWriteMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_FILL_BIT); @@ -1196,7 +1196,7 @@ void vkvg_select_font_face(VkvgContext ctx, const char* name) { if (vkvg_status(ctx)) return; RECORD(ctx, VKVG_CMD_SET_FONT_FACE, name); - vkvg_set_font(ctx, vkvg_font_create(ctx->dev, name, 12)); + vkvg_set_font(ctx, vkvg_font_create(ctx->pSurf, name, 12)); } void vkvg_load_font_from_path(VkvgContext ctx, const char* path, const char* name) { if (vkvg_status(ctx)) @@ -1359,7 +1359,7 @@ void vkvg_save(VkvgContext ctx) { } ctx->savedStencils = savedStencilsPtr; VkhImage savStencil = vkh_image_ms_create( - (VkhDevice)&ctx->dev->vkDev, dev->stencilFormat, dev->samples, ctx->pSurf->width, ctx->pSurf->height, + (VkhDevice)&ctx->dev->vkDev, dev->stencilFormat, ctx->pSurf->samples, ctx->pSurf->width, ctx->pSurf->height, VKH_MEMORY_USAGE_GPU_ONLY, VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT); ctx->savedStencils[curSaveStencil - 1] = savStencil; @@ -1403,7 +1403,7 @@ void vkvg_save(VkvgContext ctx) { vkh_cmd_label_start(ctx->cmd, "save rp", DBG_LAB_COLOR_SAV); #endif - CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelineClipping); + CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->pipelineClipping); CmdSetStencilReference(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT | curSaveBit); CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT); @@ -1467,7 +1467,7 @@ void vkvg_restore(VkvgContext ctx) { vkh_cmd_label_start(ctx->cmd, "restore rp", DBG_LAB_COLOR_SAV); #endif - CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelineClipping); + CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->pipelineClipping); CmdSetStencilReference(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, STENCIL_CLIP_BIT | curSaveBit); CmdSetStencilCompareMask(ctx->cmd, VK_STENCIL_FRONT_AND_BACK, curSaveBit); diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c index a9fc268..6f10f76 100644 --- a/src/vkvg_context_internal.c +++ b/src/vkvg_context_internal.c @@ -530,7 +530,7 @@ void _end_render_pass(VkvgContext ctx) { #if defined(DEBUG) && defined(VKVG_DBG_UTILS) vkh_cmd_label_end(ctx->cmd); #endif - ctx->renderPassBeginInfo.renderPass = ctx->dev->renderPass; + ctx->renderPassBeginInfo.renderPass = ctx->pSurf->renderPass; } void _check_vao_size(VkvgContext ctx) { @@ -607,16 +607,16 @@ void _flush_cmd_buff(VkvgContext ctx) { void _bind_draw_pipeline(VkvgContext ctx) { switch (ctx->curOperator) { case VKVG_OPERATOR_OVER: - CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipe_OVER); + CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->pipe_OVER); break; case VKVG_OPERATOR_CLEAR: - CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipe_CLEAR); + CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->pipe_CLEAR); break; case VKVG_OPERATOR_DIFFERENCE: - CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipe_SUB); + CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->pipe_SUB); break; default: - CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipe_OVER); + CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->pipe_OVER); break; } } @@ -1602,7 +1602,7 @@ void _poly_fill(VkvgContext ctx, vec4* bounds) { _ensure_renderpass_is_started(ctx); } - CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->dev->pipelinePolyFill); + CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->pipelinePolyFill); Vertex v = {{0}, ctx->curColor, {0, 0, -1}}; uint32_t ptrPath = 0; diff --git a/src/vkvg_device.c b/src/vkvg_device.c index 6b805e4..ea47024 100644 --- a/src/vkvg_device.c +++ b/src/vkvg_device.c @@ -68,13 +68,6 @@ void _device_init(VkvgDevice dev, const vkvg_device_create_info_t* info) { dev->vkDev = info->vkdev; dev->phy = info->phy; dev->instance = info->inst; - dev->hdpi = 72; - dev->vdpi = 72; - dev->samples = info->samples; - if (dev->samples == VK_SAMPLE_COUNT_1_BIT) - dev->deferredResolve = false; - else - dev->deferredResolve = info->deferredResolve; dev->cachedContextMaxCount = VKVG_MAX_CACHED_CONTEXT_COUNT; @@ -114,23 +107,7 @@ void _device_init(VkvgDevice dev, const vkvg_device_create_info_t* info) { //_device_create_pipeline_cache(dev); _fonts_cache_create(dev, info->fontsDirectories); - - if (dev->deferredResolve || dev->samples == VK_SAMPLE_COUNT_1_BIT) { - dev->renderPass = - _device_createRenderPassNoResolve(dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD); - dev->renderPass_ClearStencil = - _device_createRenderPassNoResolve(dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_CLEAR); - dev->renderPass_ClearAll = - _device_createRenderPassNoResolve(dev, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_CLEAR); - } else { - dev->renderPass = _device_createRenderPassMS(dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD); - dev->renderPass_ClearStencil = - _device_createRenderPassMS(dev, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_CLEAR); - dev->renderPass_ClearAll = - _device_createRenderPassMS(dev, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_CLEAR); - } _device_createDescriptorSetLayout(dev); - _device_setupPipelines(dev); _device_create_empty_texture(dev, format, dev->supportedTiling); @@ -148,24 +125,12 @@ void _device_init(VkvgDevice dev, const vkvg_device_create_info_t* info) { vkh_device_set_object_name(vkhd, VK_OBJECT_TYPE_COMMAND_POOL, (uint64_t)dev->cmdPool, "Device Cmd Pool"); vkh_device_set_object_name(vkhd, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)dev->cmd, "Device Cmd Buff"); vkh_device_set_object_name(vkhd, VK_OBJECT_TYPE_FENCE, (uint64_t)dev->fence, "Device Fence"); - vkh_device_set_object_name(vkhd, VK_OBJECT_TYPE_RENDER_PASS, (uint64_t)dev->renderPass, "RP load img/stencil"); - vkh_device_set_object_name(vkhd, VK_OBJECT_TYPE_RENDER_PASS, (uint64_t)dev->renderPass_ClearStencil, - "RP clear stencil"); - vkh_device_set_object_name(vkhd, VK_OBJECT_TYPE_RENDER_PASS, (uint64_t)dev->renderPass_ClearAll, "RP clear all"); vkh_device_set_object_name(vkhd, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, (uint64_t)dev->dslSrc, "DSLayout SOURCE"); vkh_device_set_object_name(vkhd, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, (uint64_t)dev->dslFont, "DSLayout FONT"); vkh_device_set_object_name(vkhd, VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, (uint64_t)dev->dslGrad, "DSLayout GRADIENT"); vkh_device_set_object_name(vkhd, VK_OBJECT_TYPE_PIPELINE_LAYOUT, (uint64_t)dev->pipelineLayout, "PLLayout dev"); -#ifndef __APPLE__ - vkh_device_set_object_name(vkhd, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipelinePolyFill, "PL Poly fill"); -#endif - vkh_device_set_object_name(vkhd, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipelineClipping, "PL Clipping"); - vkh_device_set_object_name(vkhd, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipe_OVER, "PL draw Over"); - vkh_device_set_object_name(vkhd, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipe_SUB, "PL draw Substract"); - vkh_device_set_object_name(vkhd, VK_OBJECT_TYPE_PIPELINE, (uint64_t)dev->pipe_CLEAR, "PL draw Clear"); - vkh_image_set_name(dev->emptyImg, "empty IMG"); vkh_device_set_object_name(vkhd, VK_OBJECT_TYPE_IMAGE_VIEW, (uint64_t)vkh_image_get_view(dev->emptyImg), "empty IMG VIEW"); @@ -438,25 +403,9 @@ void vkvg_device_destroy(VkvgDevice dev) { vkDestroyDescriptorSetLayout(dev->vkDev, dev->dslGrad, NULL); vkDestroyDescriptorSetLayout(dev->vkDev, dev->dslFont, NULL); vkDestroyDescriptorSetLayout(dev->vkDev, dev->dslSrc, NULL); -#ifndef __APPLE__ - vkDestroyPipeline(dev->vkDev, dev->pipelinePolyFill, NULL); -#endif - vkDestroyPipeline(dev->vkDev, dev->pipelineClipping, NULL); - - vkDestroyPipeline(dev->vkDev, dev->pipe_OVER, NULL); - vkDestroyPipeline(dev->vkDev, dev->pipe_SUB, NULL); - vkDestroyPipeline(dev->vkDev, dev->pipe_CLEAR, NULL); - -#ifdef VKVG_WIRED_DEBUG - vkDestroyPipeline(dev->vkDev, dev->pipelineWired, NULL); - vkDestroyPipeline(dev->vkDev, dev->pipelineLineList, NULL); -#endif vkDestroyPipelineLayout(dev->vkDev, dev->pipelineLayout, NULL); 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); vkDestroyFence(dev->vkDev, dev->fence, NULL); @@ -497,21 +446,7 @@ VkvgDevice vkvg_device_reference(VkvgDevice dev) { return dev; } uint32_t vkvg_device_get_reference_count(VkvgDevice dev) { return vkvg_device_status(dev) ? 0 : dev->references; } -// TODO dpy reorganisation -void vkvg_device_set_dpy(VkvgDevice dev, int hdpy, int vdpy) { - if (vkvg_device_status(dev)) - return; - dev->hdpi = hdpy; - dev->vdpi = vdpy; - // TODO: reset font cache -} -void vkvg_device_get_dpy(VkvgDevice dev, int* hdpy, int* vdpy) { - if (vkvg_device_status(dev)) - return; - *hdpy = dev->hdpi; - *vdpy = dev->vdpi; -} #if VKVG_DBG_STATS vkvg_debug_stats_t vkvg_device_get_stats(VkvgDevice dev) { return vkvg_device_status(dev) ? (vkvg_debug_stats_t){0} : dev->debug_stats; diff --git a/src/vkvg_device_internal.c b/src/vkvg_device_internal.c index 497e911..c3e61bc 100644 --- a/src/vkvg_device_internal.c +++ b/src/vkvg_device_internal.c @@ -28,7 +28,6 @@ #include "vkvg_device_internal.h" #include "vkvg_context_internal.h" -#include "shaders.h" uint32_t vkvg_log_level = VKVG_LOG_DEBUG; #ifdef VKVG_WIRED_DEBUG @@ -73,333 +72,6 @@ void _device_create_pipeline_cache(VkvgDevice dev) { VK_CHECK_RESULT(vkCreatePipelineCache(dev->vkDev, &pipelineCacheCreateInfo, NULL, &dev->pipelineCache)); } -VkRenderPass _device_createRenderPassNoResolve(VkvgDevice dev, VkAttachmentLoadOp loadOp, - VkAttachmentLoadOp stencilLoadOp) { - VkAttachmentDescription attColor = {.format = FB_COLOR_FORMAT, - .samples = dev->samples, - .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_COLOR_ATTACHMENT_OPTIMAL, - .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; - VkAttachmentDescription attDS = {.format = dev->stencilFormat, - .samples = dev->samples, - .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, - .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, - .stencilLoadOp = stencilLoadOp, - .stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE, - .initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - .finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; - - VkAttachmentDescription attachments[] = {attColor, attDS}; - VkAttachmentReference colorRef = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; - VkAttachmentReference dsRef = {1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; - - VkSubpassDescription subpassDescription = {.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, - .colorAttachmentCount = 1, - .pColorAttachments = &colorRef, - .pDepthStencilAttachment = &dsRef}; - - VkSubpassDependency dependencies[] = { - {VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - VK_ACCESS_MEMORY_READ_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - VK_DEPENDENCY_BY_REGION_BIT}, - {0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_MEMORY_READ_BIT, - VK_DEPENDENCY_BY_REGION_BIT}, - }; - - VkRenderPassCreateInfo renderPassInfo = {.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, - .attachmentCount = 2, - .pAttachments = attachments, - .subpassCount = 1, - .pSubpasses = &subpassDescription, - .dependencyCount = 2, - .pDependencies = dependencies}; - VkRenderPass rp; - VK_CHECK_RESULT(vkCreateRenderPass(dev->vkDev, &renderPassInfo, NULL, &rp)); - return rp; -} -VkRenderPass _device_createRenderPassMS(VkvgDevice dev, VkAttachmentLoadOp loadOp, VkAttachmentLoadOp stencilLoadOp) { - VkAttachmentDescription attColor = {.format = FB_COLOR_FORMAT, - .samples = dev->samples, - .loadOp = loadOp, - .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, - .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, - .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, - .initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; - VkAttachmentDescription attColorResolve = {.format = FB_COLOR_FORMAT, - .samples = VK_SAMPLE_COUNT_1_BIT, - .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, - .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, - .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; - VkAttachmentDescription attDS = {.format = dev->stencilFormat, - .samples = dev->samples, - .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, - .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, - .stencilLoadOp = stencilLoadOp, - .stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE, - .initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - .finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; - - VkAttachmentDescription attachments[] = {attColorResolve, attDS, attColor}; - VkAttachmentReference resolveRef = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; - VkAttachmentReference dsRef = {1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; - VkAttachmentReference colorRef = {2, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; - - VkSubpassDescription subpassDescription = {.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, - .colorAttachmentCount = 1, - .pColorAttachments = &colorRef, - .pResolveAttachments = &resolveRef, - .pDepthStencilAttachment = &dsRef}; - - VkSubpassDependency dependencies[] = { - {VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - VK_ACCESS_MEMORY_READ_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - VK_DEPENDENCY_BY_REGION_BIT}, - {0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_MEMORY_READ_BIT, - VK_DEPENDENCY_BY_REGION_BIT}, - }; - - VkRenderPassCreateInfo renderPassInfo = {.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, - .attachmentCount = 3, - .pAttachments = attachments, - .subpassCount = 1, - .pSubpasses = &subpassDescription, - .dependencyCount = 2, - .pDependencies = dependencies}; - VkRenderPass rp; - VK_CHECK_RESULT(vkCreateRenderPass(dev->vkDev, &renderPassInfo, NULL, &rp)); - return rp; -} - -void _device_setupPipelines(VkvgDevice dev) { - VkGraphicsPipelineCreateInfo pipelineCreateInfo = {.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, - .renderPass = dev->renderPass}; - - VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, - .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN}; - - VkPipelineRasterizationStateCreateInfo rasterizationState = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, - .polygonMode = VK_POLYGON_MODE_FILL, - .cullMode = VK_CULL_MODE_NONE, - .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE, - .depthClampEnable = VK_FALSE, - .rasterizerDiscardEnable = VK_FALSE, - .depthBiasEnable = VK_FALSE, - .lineWidth = 1.0f}; - - VkPipelineColorBlendAttachmentState blendAttachmentState = { - .colorWriteMask = 0x0, - .blendEnable = VK_TRUE, -#ifdef VKVG_PREMULT_ALPHA - .srcColorBlendFactor = VK_BLEND_FACTOR_ONE, - .dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, - .colorBlendOp = VK_BLEND_OP_ADD, - .srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE, - .dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, - .alphaBlendOp = VK_BLEND_OP_ADD, -#else - .srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA, - .dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, - .colorBlendOp = VK_BLEND_OP_ADD, - .srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE, - .dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO, - .alphaBlendOp = VK_BLEND_OP_ADD, -#endif - }; - - VkPipelineColorBlendStateCreateInfo colorBlendState = {.sType = - VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, - .attachmentCount = 1, - .pAttachments = &blendAttachmentState}; - - /*failOp,passOp,depthFailOp,compareOp, compareMask, writeMask, reference;*/ - VkStencilOpState polyFillOpState = {VK_STENCIL_OP_KEEP, - VK_STENCIL_OP_INVERT, - VK_STENCIL_OP_KEEP, - VK_COMPARE_OP_EQUAL, - STENCIL_CLIP_BIT, - STENCIL_FILL_BIT, - 0}; - VkStencilOpState clipingOpState = {VK_STENCIL_OP_ZERO, - VK_STENCIL_OP_REPLACE, - VK_STENCIL_OP_KEEP, - VK_COMPARE_OP_EQUAL, - STENCIL_FILL_BIT, - STENCIL_ALL_BIT, - 0x2}; - VkStencilOpState stencilOpState = {VK_STENCIL_OP_KEEP, - VK_STENCIL_OP_ZERO, - VK_STENCIL_OP_KEEP, - VK_COMPARE_OP_EQUAL, - STENCIL_FILL_BIT, - STENCIL_FILL_BIT, - 0x1}; - - VkPipelineDepthStencilStateCreateInfo dsStateCreateInfo = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, - .depthTestEnable = VK_FALSE, - .depthWriteEnable = VK_FALSE, - .depthCompareOp = VK_COMPARE_OP_ALWAYS, - .stencilTestEnable = VK_TRUE, - .front = polyFillOpState, - .back = polyFillOpState}; - - VkDynamicState dynamicStateEnables[] = { - VK_DYNAMIC_STATE_VIEWPORT, - VK_DYNAMIC_STATE_SCISSOR, - VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, - VK_DYNAMIC_STATE_STENCIL_REFERENCE, - VK_DYNAMIC_STATE_STENCIL_WRITE_MASK, - }; - VkPipelineDynamicStateCreateInfo dynamicState = {.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, - .dynamicStateCount = 2, - .pDynamicStates = dynamicStateEnables}; - - VkPipelineViewportStateCreateInfo viewportState = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, .viewportCount = 1, .scissorCount = 1}; - - VkPipelineMultisampleStateCreateInfo multisampleState = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, .rasterizationSamples = dev->samples}; - /*if (dev->samples != VK_SAMPLE_COUNT_1_BIT){ - multisampleState.sampleShadingEnable = VK_TRUE; - multisampleState.minSampleShading = 0.5f; - }*/ - VkVertexInputBindingDescription vertexInputBinding = { - .binding = 0, .stride = sizeof(Vertex), .inputRate = VK_VERTEX_INPUT_RATE_VERTEX}; - - VkVertexInputAttributeDescription vertexInputAttributs[3] = {{0, 0, VK_FORMAT_R32G32_SFLOAT, 0}, - {1, 0, VK_FORMAT_R8G8B8A8_UNORM, 8}, - {2, 0, VK_FORMAT_R32G32B32_SFLOAT, 12}}; - - VkPipelineVertexInputStateCreateInfo vertexInputState = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, - .vertexBindingDescriptionCount = 1, - .pVertexBindingDescriptions = &vertexInputBinding, - .vertexAttributeDescriptionCount = 3, - .pVertexAttributeDescriptions = vertexInputAttributs}; -#ifdef VKVG_WIRED_DEBUG - VkShaderModule modVert, modFrag, modFragWired; -#else - VkShaderModule modVert, modFrag; -#endif - VkShaderModuleCreateInfo createInfo = {.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, - .pCode = (uint32_t*)vkvg_main_vert_spv, - .codeSize = vkvg_main_vert_spv_len}; - VK_CHECK_RESULT(vkCreateShaderModule(dev->vkDev, &createInfo, NULL, &modVert)); -#if defined(VKVG_LCD_FONT_FILTER) && defined(FT_CONFIG_OPTION_SUBPIXEL_RENDERING) - createInfo.pCode = (uint32_t*)vkvg_main_lcd_frag_spv; - createInfo.codeSize = vkvg_main_lcd_frag_spv_len; -#else - createInfo.pCode = (uint32_t*)vkvg_main_frag_spv; - createInfo.codeSize = vkvg_main_frag_spv_len; -#endif - VK_CHECK_RESULT(vkCreateShaderModule(dev->vkDev, &createInfo, NULL, &modFrag)); - - VkPipelineShaderStageCreateInfo vertStage = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - .stage = VK_SHADER_STAGE_VERTEX_BIT, - .module = modVert, - .pName = "main", - }; - VkPipelineShaderStageCreateInfo fragStage = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - .stage = VK_SHADER_STAGE_FRAGMENT_BIT, - .module = modFrag, - .pName = "main", - }; - - // Use specialization constants to pass number of samples to the shader (used for MSAA resolve) - /*VkSpecializationMapEntry specializationEntry = { - .constantID = 0, - .offset = 0, - .size = sizeof(uint32_t)}; - uint32_t specializationData = VKVG_SAMPLES; - VkSpecializationInfo specializationInfo = { - .mapEntryCount = 1, - .pMapEntries = &specializationEntry, - .dataSize = sizeof(specializationData), - .pData = &specializationData};*/ - - VkPipelineShaderStageCreateInfo shaderStages[] = {vertStage, fragStage}; - - pipelineCreateInfo.stageCount = 1; - pipelineCreateInfo.pStages = shaderStages; - pipelineCreateInfo.pVertexInputState = &vertexInputState; - pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState; - pipelineCreateInfo.pViewportState = &viewportState; - pipelineCreateInfo.pRasterizationState = &rasterizationState; - pipelineCreateInfo.pMultisampleState = &multisampleState; - pipelineCreateInfo.pColorBlendState = &colorBlendState; - pipelineCreateInfo.pDepthStencilState = &dsStateCreateInfo; - pipelineCreateInfo.pDynamicState = &dynamicState; - pipelineCreateInfo.layout = dev->pipelineLayout; - -#ifndef __APPLE__ - VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, - &dev->pipelinePolyFill)); -#endif - - inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - dsStateCreateInfo.back = dsStateCreateInfo.front = clipingOpState; - dynamicState.dynamicStateCount = 5; - VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, - &dev->pipelineClipping)); - - dsStateCreateInfo.back = dsStateCreateInfo.front = stencilOpState; - blendAttachmentState.colorWriteMask = 0xf; - dynamicState.dynamicStateCount = 3; - pipelineCreateInfo.stageCount = 2; - VK_CHECK_RESULT( - vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipe_OVER)); - - blendAttachmentState.alphaBlendOp = blendAttachmentState.colorBlendOp = VK_BLEND_OP_SUBTRACT; - VK_CHECK_RESULT( - vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipe_SUB)); - - colorBlendState.logicOpEnable = VK_TRUE; - blendAttachmentState.blendEnable = VK_FALSE; - colorBlendState.logicOp = VK_LOGIC_OP_CLEAR; - VK_CHECK_RESULT( - vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipe_CLEAR)); - -#ifdef VKVG_WIRED_DEBUG - colorBlendState.logicOpEnable = VK_FALSE; - blendAttachmentState.blendEnable = VK_TRUE; - colorBlendState.logicOp = VK_LOGIC_OP_CLEAR; - - createInfo.pCode = (uint32_t*)wired_frag_spv; - - createInfo.codeSize = wired_frag_spv_len; - VK_CHECK_RESULT(vkCreateShaderModule(dev->vkDev, &createInfo, NULL, &modFragWired)); - - shaderStages[1].module = modFragWired; - - rasterizationState.polygonMode = VK_POLYGON_MODE_LINE; - VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, - &dev->pipelineLineList)); - - inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; - rasterizationState.polygonMode = VK_POLYGON_MODE_FILL; - VK_CHECK_RESULT( - vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipelineWired)); - - vkDestroyShaderModule(dev->vkDev, modFragWired, NULL); -#endif - - vkDestroyShaderModule(dev->vkDev, modVert, NULL); - vkDestroyShaderModule(dev->vkDev, modFrag, NULL); -} - void _device_createDescriptorSetLayout(VkvgDevice dev) { VkDescriptorSetLayoutBinding dsLayoutBinding = {0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, diff --git a/src/vkvg_device_internal.h b/src/vkvg_device_internal.h index a436cd9..a455d42 100644 --- a/src/vkvg_device_internal.h +++ b/src/vkvg_device_internal.h @@ -79,21 +79,11 @@ typedef struct _vkvg_device_t { bool threadAware; /**< if true, mutex is created and guard device queue and caches access */ VkhQueue gQueue; /**< Vulkan Queue with Graphic flag */ - 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 */ VkCommandBuffer cmd; /**< Global command buffer */ VkFence fence; /**< this fence is kept signaled when idle, wait and reset are called before each recording. */ - VkPipeline pipe_OVER; /**< default operator */ - VkPipeline pipe_SUB; - VkPipeline pipe_CLEAR; /**< clear operator */ - - VkPipeline pipelinePolyFill; /**< even-odd polygon filling first step */ - VkPipeline pipelineClipping; /**< draw on stencil to update clipping regions */ VkPipelineCache pipelineCache; /**< speed up startup by caching configured pipelines on disk */ VkPipelineLayout pipelineLayout; /**< layout common to all pipelines */ @@ -101,13 +91,9 @@ typedef struct _vkvg_device_t { VkDescriptorSetLayout dslSrc; /**< context source surface descriptors layout */ VkDescriptorSetLayout dslGrad; /**< context gradient descriptors layout */ - 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 */ + VkhImage emptyImg; /**< prevent unbound descriptor to trigger Validation error 61 */ bool deferredResolve; /**< if true, resolve only on context destruction and set as source */ _font_cache_t* fontCache; /**< Store everything relative to common font caching system */ diff --git a/src/vkvg_fonts.c b/src/vkvg_fonts.c index 7d7c356..017dbe6 100644 --- a/src/vkvg_fonts.c +++ b/src/vkvg_fonts.c @@ -4,6 +4,7 @@ #include "vkvg_fonts.h" #include "vkvg_context_internal.h" #include "vkvg_device_internal.h" +#include "vkvg_surface_internal.h" #include "vkh.h" @@ -712,6 +713,8 @@ bool try_get_font_size (FontFace face, uint32_t pt26_6, signed long* coords, Vkv for (int i = 0; i < face->sizes.count; ++i) { VkvgFont f = face->sizes.elements[i]; if (f->charSize == pt26_6) { + if (!coords) + return true; for (int axe = 0; axe < face->numAxis; ++axe) { if (f->coords[axe] != coords[axe]) return false; @@ -994,7 +997,7 @@ void* vkvg_font_get_face(VkvgFont font) { #endif } -VkvgFont _create_font_from_face (VkvgDevice dev, FontFace face, float pointSize, signed long* coords) { +VkvgFont _create_font_from_face (VkvgSurface surf, FontFace face, float pointSize, signed long* coords) { VkvgFont font = (VkvgFont)calloc(1, sizeof(vkvg_font_t)); if (!font) { LOGE("Create font failed, no memory\n"); @@ -1002,6 +1005,7 @@ VkvgFont _create_font_from_face (VkvgDevice dev, FontFace face, float pointSize, } font->face = face; + VkvgDevice dev = surf->dev; #ifdef VKVG_USE_FREETYPE if (dev->threadAware) @@ -1027,7 +1031,8 @@ VkvgFont _create_font_from_face (VkvgDevice dev, FontFace face, float pointSize, FT_CHECK_RES(FT_New_Size (face->face, &font->ftSize)); FT_CHECK_RES(FT_Activate_Size(font->ftSize)); - FT_CHECK_RES(FT_Set_Char_Size(face->face, 0, font->charSize, dev->hdpi, dev->vdpi)); + //TODO:handle fixed sizes + FT_CHECK_RES(FT_Set_Char_Size(face->face, 0, font->charSize, surf->hdpi, surf->vdpi)); if (font->coords) { FT_Set_Var_Design_Coordinates(face->face, font->face->numAxis, font->coords); font->face->coords = font->coords; @@ -1070,20 +1075,20 @@ VkvgFont _create_font_from_face (VkvgDevice dev, FontFace face, float pointSize, return font; } -VkvgFont vkvg_font_create_from_file (VkvgDevice dev, const char* fontFilePath, int faceIndex, float pointSize) { +VkvgFont vkvg_font_create_from_file (VkvgSurface surf, const char* fontFilePath, int faceIndex, float pointSize) { FontFace face = NULL; - if (!try_create_font_face_from_path(dev, fontFilePath, faceIndex, &face) || !face) { + if (!try_create_font_face_from_path(surf->dev, fontFilePath, faceIndex, &face) || !face) { return NULL; } - return _create_font_from_face(dev, face, pointSize, NULL); + return _create_font_from_face(surf, face, pointSize, NULL); } -VkvgFont vkvg_font_create (VkvgDevice dev, const char* query, float pointSize) { +VkvgFont vkvg_font_create (VkvgSurface surf, const char* query, float pointSize) { uint32_t pt26_6 = (uint32_t)(pointSize * 64.f); VkvgFont font = NULL; FontFace face = NULL; signed long* coords = NULL; unsigned int numAxis = 0; - if (try_get_or_create_font_face_from_query(dev, query, &face, &coords)) { + if (try_get_or_create_font_face_from_query(surf->dev, query, &face, &coords)) { if (try_get_font_size(face, pt26_6, coords, &font)) { vkvg_font_reference(font); return font; @@ -1092,7 +1097,7 @@ VkvgFont vkvg_font_create (VkvgDevice dev, const char* query, float pointSize) { if (!face) return NULL; - return _create_font_from_face(dev, face, pointSize, coords); + return _create_font_from_face(surf, face, pointSize, coords); } VkvgFont vkvg_font_reference(VkvgFont font) { if (!vkvg_font_status(font)) diff --git a/src/vkvg_surface.c b/src/vkvg_surface.c index b52eea2..6d10df8 100644 --- a/src/vkvg_surface.c +++ b/src/vkvg_surface.c @@ -212,8 +212,27 @@ void vkvg_surface_destroy(VkvgSurface surf) { LOG(VKVG_LOG_INFO, "DESTROY Surface\n"); + VkvgDevice dev = surf->dev; + +#ifndef __APPLE__ + vkDestroyPipeline(dev->vkDev, surf->pipelinePolyFill, NULL); +#endif + vkDestroyPipeline(dev->vkDev, surf->pipelineClipping, NULL); + + vkDestroyPipeline(dev->vkDev, surf->pipe_OVER, NULL); + vkDestroyPipeline(dev->vkDev, surf->pipe_SUB, NULL); + vkDestroyPipeline(dev->vkDev, surf->pipe_CLEAR, NULL); + +#ifdef VKVG_WIRED_DEBUG + vkDestroyPipeline(dev->vkDev, surf->pipelineWired, NULL); + vkDestroyPipeline(dev->vkDev, surf->pipelineLineList, NULL); +#endif + vkDestroyCommandPool(surf->dev->vkDev, surf->cmdPool, NULL); vkDestroyFramebuffer(surf->dev->vkDev, surf->fb, NULL); + vkDestroyRenderPass(surf->dev->vkDev, surf->renderPass, NULL); + vkDestroyRenderPass(surf->dev->vkDev, surf->renderPass_ClearStencil, NULL); + vkDestroyRenderPass(surf->dev->vkDev, surf->renderPass_ClearAll, NULL); if (!surf->img->imported) vkh_image_destroy(surf->img); @@ -275,6 +294,18 @@ uint32_t vkvg_surface_get_height(VkvgSurface surf) { return 0; return surf->height; } +void vkvg_surface_set_dpy(VkvgSurface surf, int hdpy, int vdpy) { + if (vkvg_surface_status(surf)) + return; + surf->hdpi = hdpy; + surf->vdpi = vdpy; +} +void vkvg_surface_get_dpy(VkvgSurface surf, int* hdpy, int* vdpy) { + if (vkvg_surface_status(surf)) + return; + *hdpy = surf->hdpi; + *vdpy = surf->vdpi; +} vkvg_status_t vkvg_surface_write_to_png(VkvgSurface surf, const char* path) { if (vkvg_surface_status(surf)) { diff --git a/src/vkvg_surface_internal.c b/src/vkvg_surface_internal.c index 8d15d2b..2c794f6 100644 --- a/src/vkvg_surface_internal.c +++ b/src/vkvg_surface_internal.c @@ -22,9 +22,13 @@ #include "vkvg_device_internal.h" #include "vkvg_surface_internal.h" +#include "vkvg_context_internal.h" + #include "vkh_image.h" #include "vkh_queue.h" +#include "shaders.h" + void _explicit_ms_resolve(VkvgSurface surf) { LOCK_SURFACE(surf) @@ -90,7 +94,7 @@ void _clear_surface(VkvgSurface surf, VkImageAspectFlags aspect) { VkImageSubresourceRange range = {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1}; VkhImage img = surf->imgMS; - if (surf->dev->samples == VK_SAMPLE_COUNT_1_BIT) + if (surf->samples == VK_SAMPLE_COUNT_1_BIT) img = surf->img; vkh_image_set_layout(cmd, img, VK_IMAGE_ASPECT_COLOR_BIT, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, @@ -124,6 +128,332 @@ void _clear_surface(VkvgSurface surf, VkImageAspectFlags aspect) { UNLOCK_SURFACE(surf) } +VkRenderPass _createRenderPassNoResolve(VkvgSurface surf, VkAttachmentLoadOp loadOp, + VkAttachmentLoadOp stencilLoadOp) { + VkAttachmentDescription attColor = {.format = FB_COLOR_FORMAT, + .samples = surf->samples, + .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_COLOR_ATTACHMENT_OPTIMAL, + .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; + VkAttachmentDescription attDS = {.format = surf->dev->stencilFormat, + .samples = surf->samples, + .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, + .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, + .stencilLoadOp = stencilLoadOp, + .stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE, + .initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + .finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; + + VkAttachmentDescription attachments[] = {attColor, attDS}; + VkAttachmentReference colorRef = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; + VkAttachmentReference dsRef = {1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; + + VkSubpassDescription subpassDescription = {.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, + .colorAttachmentCount = 1, + .pColorAttachments = &colorRef, + .pDepthStencilAttachment = &dsRef}; + + VkSubpassDependency dependencies[] = { + {VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_ACCESS_MEMORY_READ_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_DEPENDENCY_BY_REGION_BIT}, + {0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_MEMORY_READ_BIT, + VK_DEPENDENCY_BY_REGION_BIT}, + }; + + VkRenderPassCreateInfo renderPassInfo = {.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + .attachmentCount = 2, + .pAttachments = attachments, + .subpassCount = 1, + .pSubpasses = &subpassDescription, + .dependencyCount = 2, + .pDependencies = dependencies}; + VkRenderPass rp; + VK_CHECK_RESULT(vkCreateRenderPass(surf->dev->vkDev, &renderPassInfo, NULL, &rp)); + return rp; +} +VkRenderPass _createRenderPassMS(VkvgSurface surf, VkAttachmentLoadOp loadOp, VkAttachmentLoadOp stencilLoadOp) { + VkAttachmentDescription attColor = {.format = FB_COLOR_FORMAT, + .samples = surf->samples, + .loadOp = loadOp, + .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, + .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, + .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, + .initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; + VkAttachmentDescription attColorResolve = {.format = FB_COLOR_FORMAT, + .samples = VK_SAMPLE_COUNT_1_BIT, + .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, + .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, + .finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; + VkAttachmentDescription attDS = {.format = surf->dev->stencilFormat, + .samples = surf->samples, + .loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE, + .storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE, + .stencilLoadOp = stencilLoadOp, + .stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE, + .initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + .finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; + + VkAttachmentDescription attachments[] = {attColorResolve, attDS, attColor}; + VkAttachmentReference resolveRef = {0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; + VkAttachmentReference dsRef = {1, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL}; + VkAttachmentReference colorRef = {2, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL}; + + VkSubpassDescription subpassDescription = {.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS, + .colorAttachmentCount = 1, + .pColorAttachments = &colorRef, + .pResolveAttachments = &resolveRef, + .pDepthStencilAttachment = &dsRef}; + + VkSubpassDependency dependencies[] = { + {VK_SUBPASS_EXTERNAL, 0, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_ACCESS_MEMORY_READ_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_DEPENDENCY_BY_REGION_BIT}, + {0, VK_SUBPASS_EXTERNAL, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_MEMORY_READ_BIT, + VK_DEPENDENCY_BY_REGION_BIT}, + }; + + VkRenderPassCreateInfo renderPassInfo = {.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, + .attachmentCount = 3, + .pAttachments = attachments, + .subpassCount = 1, + .pSubpasses = &subpassDescription, + .dependencyCount = 2, + .pDependencies = dependencies}; + VkRenderPass rp; + VK_CHECK_RESULT(vkCreateRenderPass(surf->dev->vkDev, &renderPassInfo, NULL, &rp)); + return rp; +} +void _setupPipelines(VkvgSurface surf) { + VkvgDevice dev = surf->dev; + VkGraphicsPipelineCreateInfo pipelineCreateInfo = {.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, + .renderPass = surf->renderPass}; + + VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, + .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN}; + + VkPipelineRasterizationStateCreateInfo rasterizationState = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, + .polygonMode = VK_POLYGON_MODE_FILL, + .cullMode = VK_CULL_MODE_NONE, + .frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE, + .depthClampEnable = VK_FALSE, + .rasterizerDiscardEnable = VK_FALSE, + .depthBiasEnable = VK_FALSE, + .lineWidth = 1.0f}; + + VkPipelineColorBlendAttachmentState blendAttachmentState = { + .colorWriteMask = 0x0, + .blendEnable = VK_TRUE, +#ifdef VKVG_PREMULT_ALPHA + .srcColorBlendFactor = VK_BLEND_FACTOR_ONE, + .dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + .colorBlendOp = VK_BLEND_OP_ADD, + .srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE, + .dstAlphaBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + .alphaBlendOp = VK_BLEND_OP_ADD, +#else + .srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA, + .dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + .colorBlendOp = VK_BLEND_OP_ADD, + .srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE, + .dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO, + .alphaBlendOp = VK_BLEND_OP_ADD, +#endif + }; + + VkPipelineColorBlendStateCreateInfo colorBlendState = {.sType = + VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, + .attachmentCount = 1, + .pAttachments = &blendAttachmentState}; + + /*failOp,passOp,depthFailOp,compareOp, compareMask, writeMask, reference;*/ + VkStencilOpState polyFillOpState = {VK_STENCIL_OP_KEEP, + VK_STENCIL_OP_INVERT, + VK_STENCIL_OP_KEEP, + VK_COMPARE_OP_EQUAL, + STENCIL_CLIP_BIT, + STENCIL_FILL_BIT, + 0}; + VkStencilOpState clipingOpState = {VK_STENCIL_OP_ZERO, + VK_STENCIL_OP_REPLACE, + VK_STENCIL_OP_KEEP, + VK_COMPARE_OP_EQUAL, + STENCIL_FILL_BIT, + STENCIL_ALL_BIT, + 0x2}; + VkStencilOpState stencilOpState = {VK_STENCIL_OP_KEEP, + VK_STENCIL_OP_ZERO, + VK_STENCIL_OP_KEEP, + VK_COMPARE_OP_EQUAL, + STENCIL_FILL_BIT, + STENCIL_FILL_BIT, + 0x1}; + + VkPipelineDepthStencilStateCreateInfo dsStateCreateInfo = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, + .depthTestEnable = VK_FALSE, + .depthWriteEnable = VK_FALSE, + .depthCompareOp = VK_COMPARE_OP_ALWAYS, + .stencilTestEnable = VK_TRUE, + .front = polyFillOpState, + .back = polyFillOpState}; + + VkDynamicState dynamicStateEnables[] = { + VK_DYNAMIC_STATE_VIEWPORT, + VK_DYNAMIC_STATE_SCISSOR, + VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, + VK_DYNAMIC_STATE_STENCIL_REFERENCE, + VK_DYNAMIC_STATE_STENCIL_WRITE_MASK, + }; + VkPipelineDynamicStateCreateInfo dynamicState = {.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, + .dynamicStateCount = 2, + .pDynamicStates = dynamicStateEnables}; + + VkPipelineViewportStateCreateInfo viewportState = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, .viewportCount = 1, .scissorCount = 1}; + + VkPipelineMultisampleStateCreateInfo multisampleState = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT}; + /*if (dev->samples != VK_SAMPLE_COUNT_1_BIT){ + multisampleState.sampleShadingEnable = VK_TRUE; + multisampleState.minSampleShading = 0.5f; + }*/ + VkVertexInputBindingDescription vertexInputBinding = { + .binding = 0, .stride = sizeof(Vertex), .inputRate = VK_VERTEX_INPUT_RATE_VERTEX}; + + VkVertexInputAttributeDescription vertexInputAttributs[3] = {{0, 0, VK_FORMAT_R32G32_SFLOAT, 0}, + {1, 0, VK_FORMAT_R8G8B8A8_UNORM, 8}, + {2, 0, VK_FORMAT_R32G32B32_SFLOAT, 12}}; + + VkPipelineVertexInputStateCreateInfo vertexInputState = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, + .vertexBindingDescriptionCount = 1, + .pVertexBindingDescriptions = &vertexInputBinding, + .vertexAttributeDescriptionCount = 3, + .pVertexAttributeDescriptions = vertexInputAttributs}; +#ifdef VKVG_WIRED_DEBUG + VkShaderModule modVert, modFrag, modFragWired; +#else + VkShaderModule modVert, modFrag; +#endif + VkShaderModuleCreateInfo createInfo = {.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, + .pCode = (uint32_t*)vkvg_main_vert_spv, + .codeSize = vkvg_main_vert_spv_len}; + VK_CHECK_RESULT(vkCreateShaderModule(dev->vkDev, &createInfo, NULL, &modVert)); +#if defined(VKVG_LCD_FONT_FILTER) && defined(FT_CONFIG_OPTION_SUBPIXEL_RENDERING) + createInfo.pCode = (uint32_t*)vkvg_main_lcd_frag_spv; + createInfo.codeSize = vkvg_main_lcd_frag_spv_len; +#else + createInfo.pCode = (uint32_t*)vkvg_main_frag_spv; + createInfo.codeSize = vkvg_main_frag_spv_len; +#endif + VK_CHECK_RESULT(vkCreateShaderModule(dev->vkDev, &createInfo, NULL, &modFrag)); + + VkPipelineShaderStageCreateInfo vertStage = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_VERTEX_BIT, + .module = modVert, + .pName = "main", + }; + VkPipelineShaderStageCreateInfo fragStage = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_FRAGMENT_BIT, + .module = modFrag, + .pName = "main", + }; + + // Use specialization constants to pass number of samples to the shader (used for MSAA resolve) + /*VkSpecializationMapEntry specializationEntry = { + .constantID = 0, + .offset = 0, + .size = sizeof(uint32_t)}; + uint32_t specializationData = VKVG_SAMPLES; + VkSpecializationInfo specializationInfo = { + .mapEntryCount = 1, + .pMapEntries = &specializationEntry, + .dataSize = sizeof(specializationData), + .pData = &specializationData};*/ + + VkPipelineShaderStageCreateInfo shaderStages[] = {vertStage, fragStage}; + + pipelineCreateInfo.stageCount = 1; + pipelineCreateInfo.pStages = shaderStages; + pipelineCreateInfo.pVertexInputState = &vertexInputState; + pipelineCreateInfo.pInputAssemblyState = &inputAssemblyState; + pipelineCreateInfo.pViewportState = &viewportState; + pipelineCreateInfo.pRasterizationState = &rasterizationState; + pipelineCreateInfo.pMultisampleState = &multisampleState; + pipelineCreateInfo.pColorBlendState = &colorBlendState; + pipelineCreateInfo.pDepthStencilState = &dsStateCreateInfo; + pipelineCreateInfo.pDynamicState = &dynamicState; + pipelineCreateInfo.layout = dev->pipelineLayout; + +#ifndef __APPLE__ + VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, + &surf->pipelinePolyFill)); +#endif + + inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + dsStateCreateInfo.back = dsStateCreateInfo.front = clipingOpState; + dynamicState.dynamicStateCount = 5; + VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, + &surf->pipelineClipping)); + + dsStateCreateInfo.back = dsStateCreateInfo.front = stencilOpState; + blendAttachmentState.colorWriteMask = 0xf; + dynamicState.dynamicStateCount = 3; + pipelineCreateInfo.stageCount = 2; + VK_CHECK_RESULT( + vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &surf->pipe_OVER)); + + blendAttachmentState.alphaBlendOp = blendAttachmentState.colorBlendOp = VK_BLEND_OP_SUBTRACT; + VK_CHECK_RESULT( + vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &surf->pipe_SUB)); + + colorBlendState.logicOpEnable = VK_TRUE; + blendAttachmentState.blendEnable = VK_FALSE; + colorBlendState.logicOp = VK_LOGIC_OP_CLEAR; + VK_CHECK_RESULT( + vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &surf->pipe_CLEAR)); + +#ifdef VKVG_WIRED_DEBUG + colorBlendState.logicOpEnable = VK_FALSE; + blendAttachmentState.blendEnable = VK_TRUE; + colorBlendState.logicOp = VK_LOGIC_OP_CLEAR; + + createInfo.pCode = (uint32_t*)wired_frag_spv; + + createInfo.codeSize = wired_frag_spv_len; + VK_CHECK_RESULT(vkCreateShaderModule(dev->vkDev, &createInfo, NULL, &modFragWired)); + + shaderStages[1].module = modFragWired; + + rasterizationState.polygonMode = VK_POLYGON_MODE_LINE; + VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, + &dev->pipelineLineList)); + + inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST; + rasterizationState.polygonMode = VK_POLYGON_MODE_FILL; + VK_CHECK_RESULT( + vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipelineWired)); + + vkDestroyShaderModule(dev->vkDev, modFragWired, NULL); +#endif + + vkDestroyShaderModule(dev->vkDev, modVert, NULL); + vkDestroyShaderModule(dev->vkDev, modFrag, NULL); +} void _create_surface_main_image(VkvgSurface surf) { VkhDevice vkhd = (VkhDevice)&surf->dev->vkDev; @@ -145,9 +475,9 @@ void _create_surface_main_image(VkvgSurface surf) { // create multisample color img if sample count > 1 and the stencil buffer multisampled or not void _create_surface_secondary_images(VkvgSurface surf) { VkhDevice vkhd = (VkhDevice)&surf->dev->vkDev; - if (surf->dev->samples > VK_SAMPLE_COUNT_1_BIT) { + if (surf->samples > VK_SAMPLE_COUNT_1_BIT) { surf->imgMS = vkh_image_ms_create( - vkhd, surf->format, surf->dev->samples, surf->width, surf->height, VKH_MEMORY_USAGE_GPU_ONLY, + vkhd, surf->format, surf->samples, surf->width, surf->height, VKH_MEMORY_USAGE_GPU_ONLY, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT); vkh_image_create_descriptor(surf->imgMS, VK_IMAGE_VIEW_TYPE_2D, VK_IMAGE_ASPECT_COLOR_BIT, VK_FILTER_NEAREST, VK_FILTER_NEAREST, VK_SAMPLER_MIPMAP_MODE_NEAREST, @@ -160,7 +490,7 @@ void _create_surface_secondary_images(VkvgSurface surf) { "SURF MS color SAMPLER"); #endif } - surf->stencil = vkh_image_ms_create(vkhd, surf->dev->stencilFormat, surf->dev->samples, surf->width, surf->height, + surf->stencil = vkh_image_ms_create(vkhd, surf->dev->stencilFormat, surf->samples, surf->width, surf->height, VKH_MEMORY_USAGE_GPU_ONLY, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT); @@ -182,13 +512,13 @@ void _create_framebuffer(VkvgSurface surf) { vkh_image_get_view(surf->imgMS), }; VkFramebufferCreateInfo frameBufferCreateInfo = {.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, - .renderPass = surf->dev->renderPass, + .renderPass = surf->renderPass, .attachmentCount = 3, .pAttachments = attachments, .width = surf->width, .height = surf->height, .layers = 1}; - if (surf->dev->samples == VK_SAMPLE_COUNT_1_BIT) + if (surf->samples == VK_SAMPLE_COUNT_1_BIT) frameBufferCreateInfo.attachmentCount = 2; else if (surf->dev->deferredResolve) { attachments[0] = attachments[2]; @@ -225,14 +555,35 @@ VkvgSurface _create_surface(VkvgDevice dev, VkFormat format) { } atomic_init(&surf->references, 1); - surf->dev = dev; - surf->format = format; + surf->dev = dev; + surf->format = format; + surf->hdpi = 72; + surf->vdpi = 72; + surf->samples = VK_SAMPLE_COUNT_1_BIT; if (dev->threadAware) mtx_init(&surf->mutex, mtx_plain); VkhDevice vkhd = (VkhDevice)&surf->dev->vkDev; + if (dev->deferredResolve || surf->samples == VK_SAMPLE_COUNT_1_BIT) { + surf->renderPass = + _createRenderPassNoResolve(surf, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD); + surf->renderPass_ClearStencil = + _createRenderPassNoResolve(surf, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_CLEAR); + surf->renderPass_ClearAll = + _createRenderPassNoResolve(surf, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_CLEAR); + } else { + surf->renderPass = + _createRenderPassMS(surf, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_LOAD); + surf->renderPass_ClearStencil = + _createRenderPassMS(surf, VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_LOAD_OP_CLEAR); + surf->renderPass_ClearAll = + _createRenderPassMS(surf, VK_ATTACHMENT_LOAD_OP_CLEAR, VK_ATTACHMENT_LOAD_OP_CLEAR); + } + + _setupPipelines(surf); + surf->cmdPool = vkh_cmd_pool_create(vkhd, dev->gQueue->familyIndex, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT); vkh_cmd_buffs_create(vkhd, surf->cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1, &surf->cmd); @@ -245,6 +596,17 @@ VkvgSurface _create_surface(VkvgDevice dev, VkFormat format) { #if defined(DEBUG) && defined(VKVG_DBG_UTILS) vkh_device_set_object_name(vkhd, VK_OBJECT_TYPE_COMMAND_BUFFER, (uint64_t)surf->cmd, "vkvgSurfCmd"); + vkh_device_set_object_name(vkhd, VK_OBJECT_TYPE_RENDER_PASS, (uint64_t)surf->renderPass, "RP load img/stencil"); + vkh_device_set_object_name(vkhd, VK_OBJECT_TYPE_RENDER_PASS, (uint64_t)surf->renderPass_ClearStencil, "RP clear stencil"); + vkh_device_set_object_name(vkhd, VK_OBJECT_TYPE_RENDER_PASS, (uint64_t)surf->renderPass_ClearAll, "RP clear all"); +#ifndef __APPLE__ + vkh_device_set_object_name(vkhd, VK_OBJECT_TYPE_PIPELINE, (uint64_t)surf->pipelinePolyFill, "PL Poly fill"); +#endif + vkh_device_set_object_name(vkhd, VK_OBJECT_TYPE_PIPELINE, (uint64_t)surf->pipelineClipping, "PL Clipping"); + vkh_device_set_object_name(vkhd, VK_OBJECT_TYPE_PIPELINE, (uint64_t)surf->pipe_OVER, "PL draw Over"); + vkh_device_set_object_name(vkhd, VK_OBJECT_TYPE_PIPELINE, (uint64_t)surf->pipe_SUB, "PL draw Substract"); + vkh_device_set_object_name(vkhd, VK_OBJECT_TYPE_PIPELINE, (uint64_t)surf->pipe_CLEAR, "PL draw Clear"); + #endif vkvg_device_reference(surf->dev); return surf; diff --git a/src/vkvg_surface_internal.h b/src/vkvg_surface_internal.h index ee0be34..2c2af93 100644 --- a/src/vkvg_surface_internal.h +++ b/src/vkvg_surface_internal.h @@ -47,7 +47,17 @@ typedef struct _vkvg_surface_t { #else VkFence flushFence; // unsignaled idle. #endif - + int hdpi, /**< only used for FreeType fonts and svg loading */ + vdpi; + VkSampleCountFlags samples; /**< samples count */ + 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*/ + VkPipeline pipe_OVER; /**< default operator */ + VkPipeline pipe_SUB; + VkPipeline pipe_CLEAR; /**< clear operator */ + VkPipeline pipelinePolyFill; /**< even-odd polygon filling first step */ + VkPipeline pipelineClipping; /**< draw on stencil to update clipping regions */ } vkvg_surface; #define LOCK_SURFACE(surf) \ diff --git a/tests/common/test.c b/tests/common/test.c index 00bf912..fde3317 100644 --- a/tests/common/test.c +++ b/tests/common/test.c @@ -48,7 +48,7 @@ int single_test = -1; // if not < 0, contains the index of the single test to ru static bool paused = false; static bool offscreen = false; static bool threadAware = false; -static VkSampleCountFlags samples = VK_SAMPLE_COUNT_4_BIT; +static VkSampleCountFlags samples = VK_SAMPLE_COUNT_1_BIT; static VkPhysicalDeviceType preferedPhysicalDeviceType = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; static vk_engine_t* e; static char* saveToPng = NULL; @@ -503,7 +503,7 @@ void perform_test_offscreen(void (*testfunc)(void), const char* testName, int ar void perform_test_onscreen(void (*testfunc)(void), const char* testName, int argc, char* argv[]) { init_test(test_width, test_height); - vkvg_device_set_dpy(device, 96, 96); + vkvg_surface_set_dpy(surf, 96, 96); #ifdef VKVG_TEST_DIRECT_DRAW surfaces = (VkvgSurface*)malloc(r->imgCount * sizeof(VkvgSurface)); diff --git a/tests/fonts/allfont.c b/tests/fonts/allfont.c index 4e79fa3..36e8952 100644 --- a/tests/fonts/allfont.c +++ b/tests/fonts/allfont.c @@ -172,7 +172,7 @@ void draw(VkvgSurface surfFont) { char tmp[1024]; - VkvgFont mono = vkvg_font_create(device, "mono", 12); + VkvgFont mono = vkvg_font_create(surf, "mono", 12); for (int i = curFontStartIdx; i < font_database->nfont; i++) { FcPattern* font_entry = font_database->fonts[i]; @@ -199,7 +199,7 @@ void draw(VkvgSurface surfFont) { if (onlyVariable && !variable) continue; - VkvgFont font = vkvg_font_create (device, tmp, fontSize); + VkvgFont font = vkvg_font_create (surf, tmp, fontSize); if (vkvg_font_status(font)) { printf("Error trying to load %s, from %s\n", tmp, file_path); fflush(stdout); @@ -340,8 +340,8 @@ int main(int argc, char* argv[]) { e->gQFamIdx, 0, false };//, TESTS_DATA_ROOT "/fonts"}; device = vkvg_device_create(&info); - vkvg_device_set_dpy(device, 96,96); surf = vkvg_surface_create(device, test_width, test_height); + vkvg_surface_set_dpy(surf, 96,96); VkvgSurface surfFont = vkvg_surface_create(device, test_width, test_height); vkh_presenter_build_blit_cmd(r, vkvg_surface_get_vk_image(surf), test_width, test_height); diff --git a/tests/fonts/fontquery.c b/tests/fonts/fontquery.c index c4ab1f9..3cab712 100644 --- a/tests/fonts/fontquery.c +++ b/tests/fonts/fontquery.c @@ -282,7 +282,7 @@ void draw(VkvgSurface surfFont) { FcPatternGetString (font, FC_FAMILY, 0, &family_name); FcPatternGetString (font, FC_STYLE, 0, &style_variant); FcPatternGetBool(font, FC_VARIABLE, 0, &var); - VkvgFont f = vkvg_font_create_from_file(device, (char*)fontFile, index, fontSize); + VkvgFont f = vkvg_font_create_from_file(surf, (char*)fontFile, index, fontSize); if (vkvg_font_status(f)) { printf("Error trying to load %s, from %s\n", txtBuffCopy, fontFile); fflush(stdout); @@ -528,7 +528,7 @@ int main(int argc, char* argv[]) { strcpy (txtBuffer, "sans"); txtBuffPtr = 4; - sans16 = vkvg_font_create(device, "sans", 16); + sans16 = vkvg_font_create(surf, "sans", 16); while (!vkengine_should_close(e)) { glfwPollEvents(); diff --git a/tests/text.c b/tests/text.c index 6e131ce..82f9c02 100644 --- a/tests/text.c +++ b/tests/text.c @@ -194,8 +194,8 @@ void simple_text() { vkvg_paint(ctx); vkvg_set_source_rgb(ctx, 1, 1, 1); - VkvgFont mono = vkvg_font_create(device, "mono", 12); - VkvgFont norm = vkvg_font_create_from_file(device, "data/Proto-Sinaitic15.ttf", 0, 24); + VkvgFont mono = vkvg_font_create(surf, "mono", 12); + VkvgFont norm = vkvg_font_create_from_file(surf, "data/Proto-Sinaitic15.ttf", 0, 24); vkvg_set_font (ctx, mono); vkvg_move_to(ctx, 20, 50); vkvg_show_text(ctx, "hwhy"); @@ -228,7 +228,7 @@ void variable_text() { vkvg_paint(ctx); vkvg_set_source_rgb(ctx, 1, 1, 1); - VkvgFont noto = vkvg_font_create(device, "Noto Sans JP:fontvariations=wght=150", 30); + VkvgFont noto = vkvg_font_create(surf, "Noto Sans JP:fontvariations=wght=150", 30); vkvg_set_font (ctx, noto); vkvg_move_to(ctx, 20, 50); @@ -236,14 +236,14 @@ void variable_text() { vkvg_font_destroy(noto); - noto = vkvg_font_create(device, "Noto Sans JP:fontvariations=wght=900", 30); + noto = vkvg_font_create(surf, "Noto Sans JP:fontvariations=wght=900", 30); vkvg_set_font (ctx, noto); vkvg_move_to(ctx, 20, 150); vkvg_show_text(ctx, txt2); vkvg_font_destroy(noto); - noto = vkvg_font_create(device, "Cantarell:fontvariations=wght=900", 30); + noto = vkvg_font_create(surf, "Cantarell:fontvariations=wght=900", 30); vkvg_set_font (ctx, noto); vkvg_move_to(ctx, 20, 200); vkvg_show_text(ctx, txt); |