Set up multisampling

This commit is contained in:
Camden Dixie O'Brien committed 2025-10-05 14:50:11 +01:00
1 parent b5bda150d2
commit db8e263197
2 files changed
+97 -50

No files matched your search

+94 -50
View File
@@ -160,8 +160,9 @@ static void load_buffer(
static void create_img(
const gpu_ctx_t *ctx, VkFormat fmt, uint32_t width, uint32_t height,
VkImageUsageFlags usage, VkImageAspectFlags aspect, VkImage *img,
VkDeviceMemory *mem, VkImageView *view)
VkImageUsageFlags usage, VkSampleCountFlags samples,
VkImageAspectFlags aspect, VkImage *img, VkDeviceMemory *mem,
VkImageView *view)
{
VkResult result;
@@ -176,7 +177,7 @@ static void create_img(
.tiling = VK_IMAGE_TILING_OPTIMAL,
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.usage = usage,
.samples = VK_SAMPLE_COUNT_1_BIT,
.samples = samples,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
};
result = vkCreateImage(ctx->dev, &img_config, nullptr, img);
@@ -241,6 +242,14 @@ void gpu_init(gpu_ctx_t *ctx, GLFWwindow *window, const char *name)
ctx->inst, &dev_count, &ctx->physical_dev);
assert(result == VK_SUCCESS || result == VK_INCOMPLETE);
// Check that the physics device supports 8 samples
VkPhysicalDeviceProperties physical_dev_props;
vkGetPhysicalDeviceProperties(ctx->physical_dev, &physical_dev_props);
const VkSampleCountFlags sample_counts
= physical_dev_props.limits.framebufferColorSampleCounts
& physical_dev_props.limits.framebufferDepthSampleCounts;
assert((sample_counts & VK_SAMPLE_COUNT_8_BIT) != 0);
// Select queue family
uint32_t queue_family_count = QUEUE_FAMILY_PROP_BUFFER_SIZE;
VkQueueFamilyProperties
@@ -409,14 +418,23 @@ void gpu_init(gpu_ctx_t *ctx, GLFWwindow *window, const char *name)
ctx, VK_FORMAT_D32_SFLOAT, SHADOW_IMG_SIZE, SHADOW_IMG_SIZE,
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
| VK_IMAGE_USAGE_SAMPLED_BIT,
VK_IMAGE_ASPECT_DEPTH_BIT, &ctx->shadow_img, &ctx->shadow_mem,
&ctx->shadow_view);
VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_ASPECT_DEPTH_BIT, &ctx->shadow_img,
&ctx->shadow_mem, &ctx->shadow_view);
// Create colour image (for multisampling)
create_img(
ctx, surface_fmt.format, ctx->swapchain_extent.width,
ctx->swapchain_extent.height,
VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT
| VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
VK_SAMPLE_COUNT_8_BIT, VK_IMAGE_ASPECT_COLOR_BIT, &ctx->colour_img,
&ctx->colour_mem, &ctx->colour_view);
// Set up depth image
create_img(
ctx, VK_FORMAT_D32_SFLOAT, ctx->swapchain_extent.width,
ctx->swapchain_extent.height,
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_SAMPLE_COUNT_8_BIT,
VK_IMAGE_ASPECT_DEPTH_BIT, &ctx->depth_img, &ctx->depth_mem,
&ctx->depth_view);
@@ -437,16 +455,6 @@ void gpu_init(gpu_ctx_t *ctx, GLFWwindow *window, const char *name)
};
// Attachment configs
const VkAttachmentDescription colour_attachment = {
.format = surface_fmt.format,
.samples = VK_SAMPLE_COUNT_1_BIT,
.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,
};
const VkAttachmentDescription shadow_depth_attachment = {
.format = VK_FORMAT_D32_SFLOAT,
.samples = VK_SAMPLE_COUNT_1_BIT,
@@ -457,9 +465,19 @@ void gpu_init(gpu_ctx_t *ctx, GLFWwindow *window, const char *name)
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
};
const VkAttachmentDescription colour_attachment = {
.format = surface_fmt.format,
.samples = VK_SAMPLE_COUNT_8_BIT,
.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,
};
const VkAttachmentDescription render_depth_attachment = {
.format = VK_FORMAT_D32_SFLOAT,
.samples = VK_SAMPLE_COUNT_1_BIT,
.samples = VK_SAMPLE_COUNT_8_BIT,
.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
@@ -467,6 +485,16 @@ void gpu_init(gpu_ctx_t *ctx, GLFWwindow *window, const char *name)
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
};
const VkAttachmentDescription colour_resolve_attachment = {
.format = surface_fmt.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,
};
// Create shadow pass
const VkRenderPassCreateInfo shadow_pass_config = {
@@ -495,24 +523,14 @@ void gpu_init(gpu_ctx_t *ctx, GLFWwindow *window, const char *name)
assert(result == VK_SUCCESS);
// Create render pass
const VkAttachmentDescription attachment_descs[] = {
colour_attachment,
render_depth_attachment,
};
const VkSubpassDependency dependency = {
.srcSubpass = VK_SUBPASS_EXTERNAL,
.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
};
const VkRenderPassCreateInfo render_pass_config = {
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
.attachmentCount = NELEMS(attachment_descs),
.pAttachments = attachment_descs,
.attachmentCount = 3,
.pAttachments = (VkAttachmentDescription[]) {
colour_attachment,
render_depth_attachment,
colour_resolve_attachment,
},
.subpassCount = 1,
.pSubpasses = &(VkSubpassDescription){
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
@@ -525,9 +543,23 @@ void gpu_init(gpu_ctx_t *ctx, GLFWwindow *window, const char *name)
.attachment = 1,
.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
},
.pResolveAttachments = &(VkAttachmentReference) {
.attachment = 2,
.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
},
},
.dependencyCount = 1,
.pDependencies = &dependency,
.pDependencies = &(VkSubpassDependency) {
.srcSubpass = VK_SUBPASS_EXTERNAL,
.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
| VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
| VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
| VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
},
};
result = vkCreateRenderPass(
ctx->dev, &render_pass_config, nullptr, &ctx->render_pass);
@@ -555,13 +587,6 @@ void gpu_init(gpu_ctx_t *ctx, GLFWwindow *window, const char *name)
ctx->dev, &desc_pool_config, nullptr, &ctx->desc_pool);
assert(result == VK_SUCCESS);
// Populate multisampling configuration
const VkPipelineMultisampleStateCreateInfo multisampling_config = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
.sampleShadingEnable = VK_FALSE,
.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT,
};
// Set up colour blending configuration
const VkPipelineColorBlendAttachmentState colour_blend_attatchment = {
.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT
@@ -672,7 +697,12 @@ void gpu_init(gpu_ctx_t *ctx, GLFWwindow *window, const char *name)
},
.pViewportState = &viewport_config,
.pRasterizationState = &floor_rasterizer_config,
.pMultisampleState = &multisampling_config,
.pMultisampleState = &(VkPipelineMultisampleStateCreateInfo) {
.sType
= VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
.sampleShadingEnable = VK_FALSE,
.rasterizationSamples = VK_SAMPLE_COUNT_8_BIT,
},
.pColorBlendState = &colour_blend_config,
.layout = ctx->floor_pipeline_layout,
.renderPass = ctx->render_pass,
@@ -816,7 +846,12 @@ void gpu_init(gpu_ctx_t *ctx, GLFWwindow *window, const char *name)
.pInputAssemblyState = &input_assembly_config,
.pViewportState = &shadow_viewport_config,
.pRasterizationState = &shadow_rasterizer_config,
.pMultisampleState = &multisampling_config,
.pMultisampleState = &(VkPipelineMultisampleStateCreateInfo) {
.sType
= VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
.sampleShadingEnable = VK_FALSE,
.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT,
},
.layout = ctx->model_pipeline_layout,
.renderPass = ctx->shadow_pass,
.subpass = 0,
@@ -859,7 +894,12 @@ void gpu_init(gpu_ctx_t *ctx, GLFWwindow *window, const char *name)
.pInputAssemblyState = &input_assembly_config,
.pViewportState = &viewport_config,
.pRasterizationState = &model_rasterizer_config,
.pMultisampleState = &multisampling_config,
.pMultisampleState = &(VkPipelineMultisampleStateCreateInfo) {
.sType
= VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
.sampleShadingEnable = VK_FALSE,
.rasterizationSamples = VK_SAMPLE_COUNT_8_BIT,
},
.pColorBlendState = &colour_blend_config,
.layout = ctx->model_pipeline_layout,
.renderPass = ctx->render_pass,
@@ -902,15 +942,15 @@ void gpu_init(gpu_ctx_t *ctx, GLFWwindow *window, const char *name)
ctx->dev, &shadow_framebuf_config, nullptr, &ctx->shadow_framebuf);
assert(result == VK_SUCCESS);
for (unsigned i = 0; i < ctx->swapchain_img_count; ++i) {
VkImageView attachments[] = {
ctx->swapchain_img_views[i],
ctx->depth_view,
};
const VkFramebufferCreateInfo framebuffer_config = {
.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
.renderPass = ctx->render_pass,
.attachmentCount = 2,
.pAttachments = attachments,
.attachmentCount = 3,
.pAttachments = (VkImageView[]) {
ctx->colour_view,
ctx->depth_view,
ctx->swapchain_img_views[i],
},
.width = ctx->swapchain_extent.width,
.height = ctx->swapchain_extent.height,
.layers = 1,
@@ -1048,6 +1088,10 @@ void gpu_cleanup(const gpu_ctx_t *ctx)
vkDestroyRenderPass(ctx->dev, ctx->shadow_pass, nullptr);
vkDestroyRenderPass(ctx->dev, ctx->render_pass, nullptr);
vkDestroyImageView(ctx->dev, ctx->colour_view, nullptr);
vkDestroyImage(ctx->dev, ctx->colour_img, nullptr);
vkFreeMemory(ctx->dev, ctx->colour_mem, nullptr);
vkDestroyImageView(ctx->dev, ctx->shadow_view, nullptr);
vkDestroyImage(ctx->dev, ctx->shadow_img, nullptr);
vkFreeMemory(ctx->dev, ctx->shadow_mem, nullptr);
+3
View File
@@ -39,6 +39,9 @@ typedef struct {
VkDescriptorSetLayout floor_desc_set_layout;
VkDescriptorSetLayout desc_set_layout;
VkDescriptorPool desc_pool;
VkImage colour_img;
VkDeviceMemory colour_mem;
VkImageView colour_view;
VkRenderPass shadow_pass;
VkRenderPass render_pass;
VkDescriptorSet floor_desc_sets[MAX_FRAMES_IN_FLIGHT];