|
|
|
@ -177,6 +177,7 @@ void create_instance(ApplicationState* state) {
@@ -177,6 +177,7 @@ void create_instance(ApplicationState* state) {
|
|
|
|
|
free(extensions); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//find the queues families from which we can allocate all the types of queues we need
|
|
|
|
|
QueueFamilyIndices find_queue_families(ApplicationState* state, VkPhysicalDevice device) { |
|
|
|
|
struct QueueFamilyIndices ret = {0}; |
|
|
|
|
uint32_t queue_family_count = 0; |
|
|
|
@ -204,7 +205,7 @@ QueueFamilyIndices find_queue_families(ApplicationState* state, VkPhysicalDevice
@@ -204,7 +205,7 @@ QueueFamilyIndices find_queue_families(ApplicationState* state, VkPhysicalDevice
|
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//get supported formats and modes
|
|
|
|
|
//get supported formats and modes for swapchains
|
|
|
|
|
SwapChainSupportDetails get_swapchain_details(ApplicationState* state, VkPhysicalDevice device) { |
|
|
|
|
SwapChainSupportDetails ret = {0}; |
|
|
|
|
|
|
|
|
@ -258,6 +259,7 @@ bool extensions_supported(ApplicationState* state, VkPhysicalDevice device) {
@@ -258,6 +259,7 @@ bool extensions_supported(ApplicationState* state, VkPhysicalDevice device) {
|
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//check all the requirements for a physical device
|
|
|
|
|
void pick_physical_device(ApplicationState* state) { |
|
|
|
|
uint32_t device_count = 0; |
|
|
|
|
vkEnumeratePhysicalDevices(state->instance, &device_count, NULL); |
|
|
|
@ -504,6 +506,7 @@ void create_swap_chain(ApplicationState* state) {
@@ -504,6 +506,7 @@ void create_swap_chain(ApplicationState* state) {
|
|
|
|
|
state->swapchain_extent = extent; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//image views allow us to interact with images
|
|
|
|
|
void create_image_views(ApplicationState* state) { |
|
|
|
|
printf("creating image views\n"); |
|
|
|
|
state->swapchain_image_views = malloc(sizeof(VkImageView) * state->swapchain_image_count); |
|
|
|
@ -608,6 +611,15 @@ void create_render_pass(ApplicationState* state) {
@@ -608,6 +611,15 @@ void create_render_pass(ApplicationState* state) {
|
|
|
|
|
render_pass_info.pSubpasses = &subpass; |
|
|
|
|
|
|
|
|
|
//subpass dependencies
|
|
|
|
|
//
|
|
|
|
|
//subpasses in a render pass automatically handle image layout transitions, the transitions are controlled by
|
|
|
|
|
//subpass dependencies, which specify dependencies between various subpasses.
|
|
|
|
|
//
|
|
|
|
|
//There are implicit subpasses before and after the single subpass we have
|
|
|
|
|
//
|
|
|
|
|
//we currently have an issue where the image transition at the start of the render pass does not occur at the
|
|
|
|
|
//right time, since it assumes it happens at the start of the pipeline, but the image may not have been acquired
|
|
|
|
|
//by that point
|
|
|
|
|
VkSubpassDependency dependency = {0}; |
|
|
|
|
//implicit subpass before or after rendering is complete
|
|
|
|
|
dependency.srcSubpass = VK_SUBPASS_EXTERNAL; |
|
|
|
@ -899,6 +911,7 @@ void record_command_buffer(ApplicationState* state, VkCommandBuffer command_buff
@@ -899,6 +911,7 @@ void record_command_buffer(ApplicationState* state, VkCommandBuffer command_buff
|
|
|
|
|
|
|
|
|
|
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, state->graphics_pipeline); |
|
|
|
|
|
|
|
|
|
//setup dynamic state
|
|
|
|
|
VkViewport viewport = {0}; |
|
|
|
|
viewport.x = 0.0f; |
|
|
|
|
viewport.y = 0.0f; |
|
|
|
@ -962,15 +975,20 @@ void init_vulkan(ApplicationState* state) {
@@ -962,15 +975,20 @@ void init_vulkan(ApplicationState* state) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void draw_frame(ApplicationState* state) { |
|
|
|
|
//wait for the previous frame to be rendered
|
|
|
|
|
vkWaitForFences(state->device, 1, &state->in_flight_frames, VK_TRUE, UINT64_MAX); |
|
|
|
|
vkResetFences(state->device, 1, &state->in_flight_frames); |
|
|
|
|
|
|
|
|
|
uint32_t image_index; |
|
|
|
|
//get images from the swapchain and signal when the image is ready
|
|
|
|
|
vkAcquireNextImageKHR(state->device, state->swapchain, UINT64_MAX, state->image_available_semaph, VK_NULL_HANDLE, &image_index); |
|
|
|
|
|
|
|
|
|
//reset and setup the commands we want to run
|
|
|
|
|
vkResetCommandBuffer(state->command_buffer, 0); |
|
|
|
|
record_command_buffer(state, state->command_buffer, image_index); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//specify what to wait for before execution can begin
|
|
|
|
|
VkSubmitInfo submit_info = {0}; |
|
|
|
|
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; |
|
|
|
|
|
|
|
|
|