summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/render.c95
-rw-r--r--src/shader.frag80
-rw-r--r--src/state.h10
3 files changed, 115 insertions, 70 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;
diff --git a/src/shader.frag b/src/shader.frag
index 1818cc8..3e80e21 100644
--- a/src/shader.frag
+++ b/src/shader.frag
@@ -16,50 +16,50 @@ layout(binding = 0) uniform UniformBufferObject {
float dt;
} ubo;
-void main() {
- // float pulse = sin(ubo.time * .2) * .5 + .5;
- // outColor = vec4(fragColor * texture(texSampler, fragTexCoord).rgb * pulse, 1.0);
- //outColor = texture(texSampler, fragTexCoord);
- outColor = vec4(fragColor, 1);
-// float repeat = 10;
-// float f = mod(ubo.time, repeat);
-// if (f < repeat / 2) {
-// outColor = vec4(fragColor * radians(f) ,1);
-// } else {
-// outColor = vec4(fragColor * radians(1 - f) ,1);
-// }
-// //outColor = (vec4(1) * ubo.model + vec4(1)) * vec4(texture(texSampler, fragTexCoord).rgb * fragColor, 1.0);
-}
-
-// float noise(vec2 p) {
-// return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453);
+// void main() {
+// // float pulse = sin(ubo.time * .2) * .5 + .5;
+// // outColor = vec4(fragColor * texture(texSampler, fragTexCoord).rgb * pulse, 1.0);
+// //outColor = texture(texSampler, fragTexCoord);
+// outColor = vec4(fragColor, 1);
+// // float repeat = 10;
+// // float f = mod(ubo.time, repeat);
+// // if (f < repeat / 2) {
+// // outColor = vec4(fragColor * radians(f) ,1);
+// // } else {
+// // outColor = vec4(fragColor * radians(1 - f) ,1);
+// // }
+// // //outColor = (vec4(1) * ubo.model + vec4(1)) * vec4(texture(texSampler, fragTexCoord).rgb * fragColor, 1.0);
// }
-// float smoothNoise(vec2 p) {
-// vec2 i = floor(p);
-// vec2 f = fract(p);
-// vec2 u = f * f * (3.0 - 2.0 * f);
-// return mix(mix(noise(i + vec2(0.0, 0.0)), noise(i + vec2(1.0, 0.0)), u.x),
-// mix(noise(i + vec2(0.0, 1.0)), noise(i + vec2(1.0, 1.0)), u.x), u.y);
-// }
+float noise(vec2 p) {
+ return fract(sin(dot(p, vec2(12.9898, 78.233))) * 43758.5453);
+}
-// float fbm(vec2 p) {
-// float value = 0.0;
-// float amplitude = 0.5;
-// for (int i = 0; i < 6; i++) {
-// value += amplitude * smoothNoise(p);
-// p *= 2.0;
-// amplitude *= 0.5;
-// }
-// return value;
-// }
+float smoothNoise(vec2 p) {
+ vec2 i = floor(p);
+ vec2 f = fract(p);
+ vec2 u = f * f * (3.0 - 2.0 * f);
+ return mix(mix(noise(i + vec2(0.0, 0.0)), noise(i + vec2(1.0, 0.0)), u.x),
+ mix(noise(i + vec2(0.0, 1.0)), noise(i + vec2(1.0, 1.0)), u.x), u.y);
+}
-// void main() {
-// vec2 uv = gl_FragCoord.xy / ubo.resolution.xy;
-// vec2 p = uv * 2.0 - vec2(1.0);
-// float n = fbm(p * 5.0 - vec2(0.0, ubo.time * 2.0));
-// outColor = vec4(n, n * 0.5, 0.0, 1.0) * vec4(texture(texSampler, fragTexCoord).rgb, 1.0);
-// }
+float fbm(vec2 p) {
+ float value = 0.0;
+ float amplitude = 0.5;
+ for (int i = 0; i < 6; i++) {
+ value += amplitude * smoothNoise(p);
+ p *= 2.0;
+ amplitude *= 0.5;
+ }
+ return value;
+}
+
+void main() {
+ vec2 uv = gl_FragCoord.xy / ubo.resolution.xy;
+ vec2 p = uv * 2.0 - vec2(1.0);
+ float n = fbm(p * 5.0 - vec2(0.0, ubo.time * 2.0));
+ outColor = vec4(n, n * 0.5, 0.0, 1.0) * vec4(texture(texSampler, fragTexCoord).rgb, 1.0);
+}
// void main() {
diff --git a/src/state.h b/src/state.h
index 2f02a20..95f636b 100644
--- a/src/state.h
+++ b/src/state.h
@@ -142,13 +142,19 @@ typedef struct state {
VkDeviceMemory vertexBufferMemory;
char model_path[1000];
+
+ VkSampleCountFlagBits msaa_samples;
+
+ VkImage vk_color_image;
+ VkDeviceMemory vk_color_image_memory;
+ VkImageView vk_color_image_view;
} state_t;
static void
init_state(state_t *s)
{
- strcpy(s->model_path, "assets/viking_room.obj");
+ strcpy(s->model_path, "assets/monkey.obj");
s->camera.pos[0] = 2.0f;
s->camera.pos[1] = 2.0f;
s->camera.pos[2] = 2.0f;
@@ -198,4 +204,6 @@ init_state(state_t *s)
s->prev_frag_result = NULL;
s->polygon_mode = VK_POLYGON_MODE_FILL;
+
+ s->msaa_samples = VK_SAMPLE_COUNT_1_BIT;
}