summaryrefslogtreecommitdiffstats
path: root/src/render.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/render.c')
-rw-r--r--src/render.c95
1 files changed, 66 insertions, 29 deletions
diff --git a/src/render.c b/src/render.c
index 275752c..0f80d3a 100644
--- a/src/render.c
+++ b/src/render.c
@@ -364,6 +364,21 @@ vulkan_is_device_suitable(VkPhysicalDevice device)
&& swapChainAdequate && supportedFeatures.samplerAnisotropy;
}
+VkSampleCountFlagBits getMaxUsableSampleCount() {
+ VkPhysicalDeviceProperties physicalDeviceProperties;
+ vkGetPhysicalDeviceProperties(s.vk_physical_device, &physicalDeviceProperties);
+
+ VkSampleCountFlags counts = physicalDeviceProperties.limits.framebufferColorSampleCounts & physicalDeviceProperties.limits.framebufferDepthSampleCounts;
+ if (counts & VK_SAMPLE_COUNT_64_BIT) { return VK_SAMPLE_COUNT_64_BIT; }
+ if (counts & VK_SAMPLE_COUNT_32_BIT) { return VK_SAMPLE_COUNT_32_BIT; }
+ if (counts & VK_SAMPLE_COUNT_16_BIT) { return VK_SAMPLE_COUNT_16_BIT; }
+ if (counts & VK_SAMPLE_COUNT_8_BIT) { return VK_SAMPLE_COUNT_8_BIT; }
+ if (counts & VK_SAMPLE_COUNT_4_BIT) { return VK_SAMPLE_COUNT_4_BIT; }
+ if (counts & VK_SAMPLE_COUNT_2_BIT) { return VK_SAMPLE_COUNT_2_BIT; }
+
+ return VK_SAMPLE_COUNT_1_BIT;
+}
+
void
vulkan_pick_physical_device()
{
@@ -379,6 +394,7 @@ vulkan_pick_physical_device()
for (uint32_t i = 0; i < deviceCount; i++) {
if (vulkan_is_device_suitable(devices[i])) {
s.vk_physical_device = devices[i];
+ s.msaa_samples = getMaxUsableSampleCount();
break;
}
}
@@ -423,6 +439,7 @@ vulkan_create_logical_device()
VkPhysicalDeviceFeatures deviceFeatures = {0};
vkGetPhysicalDeviceFeatures(s.vk_physical_device, &deviceFeatures);
deviceFeatures.samplerAnisotropy = VK_TRUE;
+ //deviceFeatures.sampleRateShading = VK_TRUE;
#ifndef VKDEBUG
/* Disable robust buffer access when building without debug */
deviceFeatures.robustBufferAccess = VK_FALSE;
@@ -724,7 +741,7 @@ void
createImage(uint32_t width, uint32_t height, uint32_t mipLevels, VkFormat format,
VkImageTiling tiling, VkImageUsageFlags usage,
VkMemoryPropertyFlags properties, VkImage *image,
- VkDeviceMemory *imageMemory)
+ VkDeviceMemory *imageMemory, VkSampleCountFlagBits numSamples)
{
VkImageCreateInfo imageInfo = {0};
imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
@@ -738,7 +755,7 @@ createImage(uint32_t width, uint32_t height, uint32_t mipLevels, VkFormat format
imageInfo.tiling = tiling;
imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
imageInfo.usage = usage;
- imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;
+ imageInfo.samples = numSamples;
imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
VK_CHECK(vkCreateImage(s.vk_device, &imageInfo, NULL, image));
@@ -880,7 +897,7 @@ vulkan_create_depth_resources()
depthFormat, VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
- &s.vk_depth_image, &s.vk_depth_image_memory);
+ &s.vk_depth_image, &s.vk_depth_image_memory, s.msaa_samples);
s.vk_depth_image_view = create_image_view(s.vk_depth_image, depthFormat,
VK_IMAGE_ASPECT_DEPTH_BIT, 1);
@@ -890,6 +907,18 @@ vulkan_create_depth_resources()
VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, 1);
}
+void vulkan_create_color_resources() {
+ VkFormat colorFormat = s.vk_swap_chain_image_format;
+
+ createImage(s.vk_swap_chain_extent.width, s.vk_swap_chain_extent.height, 1,
+ colorFormat, VK_IMAGE_TILING_OPTIMAL,
+ VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT |
+ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
+ VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
+ &s.vk_color_image, &s.vk_color_image_memory, s.msaa_samples);
+ s.vk_color_image_view = create_image_view(s.vk_color_image, colorFormat, VK_IMAGE_ASPECT_COLOR_BIT, 1);
+}
+
void
vulkan_create_graphics_pipeline(VkPolygonMode polygon_mode)
{
@@ -940,7 +969,9 @@ vulkan_create_graphics_pipeline(VkPolygonMode polygon_mode)
VK_DYNAMIC_STATE_VIEWPORT,
VK_DYNAMIC_STATE_SCISSOR,
VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE,
- VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE
+ VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE,
+ // TODO Make polygon mode dynamic
+ //VK_DYNAMIC_STATE_POLYGON_MODE_EXT
};
VkPipelineDynamicStateCreateInfo dynamicState = {0};
@@ -993,13 +1024,12 @@ vulkan_create_graphics_pipeline(VkPolygonMode polygon_mode)
scissor.offset = (VkOffset2D){0, 0};
scissor.extent = s.vk_swap_chain_extent;
- VkPipelineViewportStateCreateInfo viewportState = {
- .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
- .viewportCount = 1,
- .pViewports = &viewport,
- .scissorCount = 1,
- .pScissors = &scissor,
- };
+ VkPipelineViewportStateCreateInfo viewportState = {0};
+ viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
+ viewportState.viewportCount = 1;
+ viewportState.pViewports = &viewport;
+ viewportState.scissorCount = 1;
+ viewportState.pScissors = &scissor;
VkPipelineRasterizationStateCreateInfo rasterizer = {0};
rasterizer.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
@@ -1018,7 +1048,7 @@ vulkan_create_graphics_pipeline(VkPolygonMode polygon_mode)
VkPipelineMultisampleStateCreateInfo multisampling = {0};
multisampling.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
multisampling.sampleShadingEnable = VK_FALSE;
- multisampling.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
+ multisampling.rasterizationSamples = s.msaa_samples;
multisampling.minSampleShading = 1.0f; // Optional
multisampling.pSampleMask = NULL; // Optional
multisampling.alphaToCoverageEnable = VK_FALSE; // Optional
@@ -1068,7 +1098,6 @@ vulkan_create_graphics_pipeline(VkPolygonMode polygon_mode)
depthStencil.front = (VkStencilOpState){0}; // Optional
depthStencil.back = (VkStencilOpState){0}; // Optional
- // TODO depthAttachment
VkPipelineRenderingCreateInfo pipeline_rendering_create_info = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
.colorAttachmentCount = 1,
@@ -1150,7 +1179,9 @@ recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex)
VK_CHECK(vkBeginCommandBuffer(commandBuffer, &beginInfo));
vkCmdSetDepthTestEnable(commandBuffer, 1);
vkCmdSetDepthWriteEnable(commandBuffer, 1);
-
+ // TODO Make polygon mode dynamic
+ //vkCmdSetPolygonModeEXT(commandBuffer, s.polygon_mode);
+
transitionImageLayout(
s.vk_swap_chain_images[imageIndex], VK_FORMAT_R8G8B8A8_SRGB, 0,
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
@@ -1159,8 +1190,11 @@ recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex)
VkRenderingAttachmentInfo colorAttachment = {0};
colorAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
- colorAttachment.imageView = s.vk_swap_chain_image_views[imageIndex];
+ colorAttachment.imageView = s.vk_color_image_view;
colorAttachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+ colorAttachment.resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT;
+ colorAttachment.resolveImageView = s.vk_swap_chain_image_views[imageIndex];
+ colorAttachment.resolveImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
colorAttachment.clearValue.color =
@@ -1459,6 +1493,10 @@ vulkan_create_descriptor_sets()
void
cleanupSwapChain()
{
+ vkDestroyImageView(s.vk_device, s.vk_color_image_view, NULL);
+ vkDestroyImage(s.vk_device, s.vk_color_image, NULL);
+ vkFreeMemory(s.vk_device, s.vk_color_image_memory, NULL);
+
vkDestroyImageView(s.vk_device, s.vk_depth_image_view, NULL);
vkDestroyImage(s.vk_device, s.vk_depth_image, NULL);
vkFreeMemory(s.vk_device, s.vk_depth_image_memory, NULL);
@@ -1478,6 +1516,7 @@ recreateSwapChain()
vulkan_create_swap_chain();
vulkan_create_image_views();
+ vulkan_create_color_resources();
vulkan_create_depth_resources();
}
@@ -1558,7 +1597,7 @@ handle_input(bool * quit)
/* strcpy(s.model_path, "assets/human.obj"); */
if (toggle) {
- strcpy(s.model_path, "assets/monkey.obj");
+ strcpy(s.model_path, "assets/viking_room.obj");
load_model_obj();
toggle = 0;
} else {
@@ -1760,7 +1799,7 @@ vulkan_create_texture_image()
VK_IMAGE_TILING_OPTIMAL,
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &s.vk_texture_image,
- &s.vk_texture_image_memory);
+ &s.vk_texture_image_memory, VK_SAMPLE_COUNT_1_BIT);
transitionImageLayout(
s.vk_texture_image, VK_FORMAT_R8G8B8A8_SRGB, 0,
@@ -1961,7 +2000,7 @@ void load_model_gltf() {
cgltf_free(data);
}
-
+
void
init_vulkan()
{
@@ -1983,11 +2022,12 @@ init_vulkan()
vulkan_create_graphics_pipeline(s.polygon_mode);
vulkan_create_command_pool();
vulkan_create_depth_resources();
+ vulkan_create_color_resources();
vulkan_create_texture_image();
vulkan_create_texture_image_view();
vulkan_create_texture_sampler();
- //load_model_obj();
- load_model_gltf();
+ load_model_obj();
+ //load_model_gltf();
vulkan_create_vertex_buffer();
vulkan_create_index_buffer();
vulkan_create_uniform_buffers();
@@ -2107,7 +2147,6 @@ updateUniformBuffer(uint32_t currentImage, float dt)
}
float prev_time = 0;
-
void
draw_frame() {
float time = current_time();
@@ -2134,22 +2173,20 @@ draw_frame() {
// both could work
//vkResetCommandPool(s.vk_device, s.vk_command_pool, VK_COMMAND_POOL_RESET_RELEASE_RESOURCES_BIT);
vkResetCommandBuffer(s.frames[currentFrame].vk_command_buffer, 0);
+
recordCommandBuffer(s.frames[currentFrame].vk_command_buffer, imageIndex);
+ VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
+
VkSubmitInfo submitInfo = {0};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
-
- VkSemaphore waitSemaphores[] = {s.frames[currentFrame].image_available_semaphore};
- VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
submitInfo.waitSemaphoreCount = 1;
- submitInfo.pWaitSemaphores = waitSemaphores;
+ submitInfo.pWaitSemaphores = &s.frames[currentFrame].image_available_semaphore;
submitInfo.pWaitDstStageMask = waitStages;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &s.frames[currentFrame].vk_command_buffer;
-
- VkSemaphore signalSemaphores[] = {s.frames[currentFrame].render_finished_semaphore};
submitInfo.signalSemaphoreCount = 1;
- submitInfo.pSignalSemaphores = signalSemaphores;
+ submitInfo.pSignalSemaphores = &s.frames[currentFrame].render_finished_semaphore;
if (vkQueueSubmit(s.vk_graphics_queue, 1, &submitInfo, s.frames[currentFrame].in_flight_fence) != VK_SUCCESS) {
vk_log(VK_ERROR, "failed to submit draw command buffer!\n");
@@ -2159,7 +2196,7 @@ draw_frame() {
VkPresentInfoKHR presentInfo = {0};
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
presentInfo.waitSemaphoreCount = 1;
- presentInfo.pWaitSemaphores = signalSemaphores;
+ presentInfo.pWaitSemaphores = &s.frames[currentFrame].render_finished_semaphore;
presentInfo.swapchainCount = 1;
presentInfo.pSwapchains = swapChains;
presentInfo.pImageIndices = &imageIndex;