diff --git a/libs/video/renderer/vid_render_vulkan.c b/libs/video/renderer/vid_render_vulkan.c index 8441795c1..ebca7b9b0 100644 --- a/libs/video/renderer/vid_render_vulkan.c +++ b/libs/video/renderer/vid_render_vulkan.c @@ -135,12 +135,15 @@ vulkan_R_RenderFrame (SCR_Func scr_3dfunc, SCR_Func *scr_funcs) framebuffer->imageAvailableSemaphore, 0, &imageIndex); - __auto_type attachments = DARRAY_ALLOCFIXED (qfv_imageviewset_t, 3, - alloca); + int attachCount = vulkan_ctx->msaaSamples > 1 ? 3 : 2; + __auto_type attachments = DARRAY_ALLOCFIXED (qfv_imageviewset_t, + attachCount, alloca); qfv_swapchain_t *sc = vulkan_ctx->swapchain; - attachments->a[0] = vulkan_ctx->renderpass.colorImage->view; + attachments->a[0] = sc->imageViews->a[imageIndex]; attachments->a[1] = vulkan_ctx->renderpass.depthImage->view; - attachments->a[2] = sc->imageViews->a[imageIndex]; + if (attachCount > 2) { + attachments->a[2] = vulkan_ctx->renderpass.colorImage->view; + } VkRenderPass renderpass = vulkan_ctx->renderpass.renderpass; framebuffer->framebuffer = QFV_CreateFramebuffer (device, renderpass, @@ -157,15 +160,16 @@ vulkan_R_RenderFrame (SCR_Func scr_3dfunc, SCR_Func *scr_funcs) VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; - VkClearValue clearValues[2] = { + VkClearValue clearValues[3] = { { { {0.0, 0.0, 0.0, 1.0} } }, { { {1.0, 0.0} } }, + { { {0.0, 0.0, 0.0, 1.0} } }, }; VkRenderPassBeginInfo renderPassInfo = { VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, 0, vulkan_ctx->renderpass.renderpass, 0, { {0, 0}, sc->extent }, - 2, clearValues + 3, clearValues }; dfunc->vkBeginCommandBuffer (framebuffer->cmdBuffer, &beginInfo); diff --git a/libs/video/renderer/vulkan/qfpipeline.plist b/libs/video/renderer/vulkan/qfpipeline.plist index 33bc11b27..96de769c9 100644 --- a/libs/video/renderer/vulkan/qfpipeline.plist +++ b/libs/video/renderer/vulkan/qfpipeline.plist @@ -707,13 +707,75 @@ { flags = 0; format = $swapchain.format; - samples = $msaaSamples; + samples = 1; loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; 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; + finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; + }, + { + flags = 0; + format = VK_FORMAT_D32_SFLOAT; + samples = 1; + loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; + 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_UNDEFINED; + finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + }, + ); + subpasses = ( + { + pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; + colorAttachments = ( + { + attachment = 0; + layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + } + ); + depthStencilAttachment = { + attachment = 1; + layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + }; + preserveAttachments = (); + }, + ); + dependencies = ( + { + srcSubpass = VK_SUBPASS_EXTERNAL; + dstSubpass = 0; + srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + srcAccessMask = VK_ACCESS_MEMORY_READ_BIT; + dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; + }, + { + srcSubpass = 0; + dstSubpass = VK_SUBPASS_EXTERNAL; + srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; + srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + dstAccessMask = VK_ACCESS_MEMORY_READ_BIT; + dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT; + }, + ); + }; + renderpass.msaa = { + attachments = ( + { + flags = 0; + format = $swapchain.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_PRESENT_SRC_KHR; }, { flags = 0; @@ -729,13 +791,13 @@ { flags = 0; format = $swapchain.format; - samples = VK_SAMPLE_COUNT_1_BIT; - loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; + samples = $msaaSamples; + loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; 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_PRESENT_SRC_KHR; + finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; }, ); subpasses = ( @@ -743,13 +805,13 @@ pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; colorAttachments = ( { - attachment = 0; + attachment = 2; layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; } ); resolveAttachments = ( { - attachment = 2; + attachment = 0; layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; } ); diff --git a/libs/video/renderer/vulkan/renderpass.c b/libs/video/renderer/vulkan/renderpass.c index 65134ffd7..4970b050b 100644 --- a/libs/video/renderer/vulkan/renderpass.c +++ b/libs/video/renderer/vulkan/renderpass.c @@ -106,9 +106,13 @@ QFV_CreateRenderPass (qfv_device_t *device, const VkAttachmentReference *ref = &sp->pColorAttachments[j]; Sys_Printf (" c %d %d\n", ref->attachment, ref->layout); } - for (size_t j = 0; j < sp->colorAttachmentCount; j++) { - const VkAttachmentReference *ref = &sp->pResolveAttachments[j]; - Sys_Printf (" r %d %d\n", ref->attachment, ref->layout); + if (sp->pResolveAttachments) { + for (size_t j = 0; j < sp->colorAttachmentCount; j++) { + const VkAttachmentReference *ref + = &sp->pResolveAttachments[j]; + Sys_Printf (" r %d %d\n", ref->attachment, + ref->layout); + } } Sys_Printf (" pDepthStencilAttachment: %p\n", sp->pDepthStencilAttachment); diff --git a/libs/video/renderer/vulkan/vulkan_vid_common.c b/libs/video/renderer/vulkan/vulkan_vid_common.c index ddd20e82c..ff026331a 100644 --- a/libs/video/renderer/vulkan/vulkan_vid_common.c +++ b/libs/video/renderer/vulkan/vulkan_vid_common.c @@ -240,28 +240,31 @@ Vulkan_CreateRenderPass (vulkan_ctx_t *ctx) { qfv_load_pipeline (ctx); const char *name = "renderpass";//FIXME - - plitem_t *item = ctx->pipelineDef; - if (!item || !(item = PL_ObjectForKey (item, name))) { - Sys_Printf ("error loading renderpass\n"); - return; - } else { - Sys_Printf ("Found renderpass def\n"); - } qfv_device_t *device = ctx->device; VkDevice dev = device->dev; qfv_devfuncs_t *df = device->funcs; VkCommandBuffer cmd = ctx->cmdbuffer; qfv_swapchain_t *sc = ctx->swapchain; + ctx->msaaSamples = min ((VkSampleCountFlagBits) msaaSamples->int_val, + QFV_GetMaxSampleCount (device->physDev)); + if (ctx->msaaSamples > 1) { + name = "renderpass.msaa"; + } + + plitem_t *item = ctx->pipelineDef; + if (!item || !(item = PL_ObjectForKey (item, name))) { + Sys_Printf ("error loading renderpass: %s\n", name); + return; + } else { + Sys_Printf ("Found renderpass def: %s\n", name); + } + qfv_imageresource_t *colorImage = malloc (sizeof (*colorImage)); qfv_imageresource_t *depthImage = malloc (sizeof (*depthImage)); VkExtent3D extent = {sc->extent.width, sc->extent.height, 1}; - //FIXME incorporate cvar setting - ctx->msaaSamples = QFV_GetMaxSampleCount (device->physDev); - Sys_MaskPrintf (SYS_VULKAN, "color resource\n"); colorImage->image = QFV_CreateImage (device, 0, VK_IMAGE_TYPE_2D,