First attempt for general frame begin/end vulkan functionality.
Test code to draw q3 cinematic. Bugs to fix when things will settle down a bit: cinematic leaks memory, render_view function invalidates command buffer when multiple scenes are rendered in a single frame.
This commit is contained in:
parent
ab66921e14
commit
f944034d17
|
|
@ -21,6 +21,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
*/
|
||||
#include "tr_local.h"
|
||||
|
||||
// VULKAN
|
||||
#include "vk_init.h"
|
||||
#include "vk_demo.h"
|
||||
#include "vk_utils.h"
|
||||
|
||||
backEndData_t *backEndData[SMP_FRAMES];
|
||||
backEndState_t backEnd;
|
||||
|
||||
|
|
@ -639,6 +644,9 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
|
|||
#ifdef __MACOS__
|
||||
Sys_PumpEvents(); // crutch up the mac's limited buffer queue size
|
||||
#endif
|
||||
|
||||
// VULKAN
|
||||
vulkan_demo->render_view();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -727,11 +735,23 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *
|
|||
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
|
||||
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
|
||||
|
||||
// VULKAN
|
||||
vkDestroyImage(get_device(), tr.scratchImage[client]->vk_image, nullptr);
|
||||
vkDestroyImageView(get_device(), tr.scratchImage[client]->vk_image_view, nullptr);
|
||||
tr.scratchImage[client]->vk_image = vulkan_demo->create_texture(data, 4, cols, rows, tr.scratchImage[client]->vk_image_view);
|
||||
vulkan_demo->cinematic_image_view = tr.scratchImage[client]->vk_image_view;
|
||||
} else {
|
||||
if (dirty) {
|
||||
// otherwise, just subimage upload it so that drivers can tell we are going to be changing
|
||||
// it and don't try and do a texture compression
|
||||
qglTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_RGBA, GL_UNSIGNED_BYTE, data );
|
||||
|
||||
// VULKAN
|
||||
vkDestroyImage(get_device(), tr.scratchImage[client]->vk_image, nullptr);
|
||||
vkDestroyImageView(get_device(), tr.scratchImage[client]->vk_image_view, nullptr);
|
||||
tr.scratchImage[client]->vk_image = vulkan_demo->create_texture(data, 4, cols, rows, tr.scratchImage[client]->vk_image_view);
|
||||
vulkan_demo->cinematic_image_view = tr.scratchImage[client]->vk_image_view;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -754,6 +774,9 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *
|
|||
qglTexCoord2f ( 0.5f / cols, ( rows - 0.5f ) / rows );
|
||||
qglVertex2f (x, y+h);
|
||||
qglEnd ();
|
||||
|
||||
// VULKAN
|
||||
vulkan_demo->render_cinematic_frame();
|
||||
}
|
||||
|
||||
void RE_UploadCinematic (int w, int h, int cols, int rows, const byte *data, int client, qboolean dirty) {
|
||||
|
|
@ -918,6 +941,28 @@ const void *RB_DrawBuffer( const void *data ) {
|
|||
qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||
}
|
||||
|
||||
// VULKAN
|
||||
VkResult result = vkAcquireNextImageKHR(get_device(), get_swapchain(), UINT64_MAX, vulkan_demo->image_acquired, VK_NULL_HANDLE, &vulkan_demo->swapchain_image_index);
|
||||
check_vk_result(result, "vkAcquireNextImageKHR");
|
||||
|
||||
result = vkWaitForFences(get_device(), 1, &vulkan_demo->rendering_finished_fence, VK_FALSE, 1e9);
|
||||
check_vk_result(result, "vkWaitForFences");
|
||||
result = vkResetFences(get_device(), 1, &vulkan_demo->rendering_finished_fence);
|
||||
check_vk_result(result, "vkResetFences");
|
||||
|
||||
VkCommandBufferBeginInfo begin_info;
|
||||
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
begin_info.pNext = nullptr;
|
||||
begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||
begin_info.pInheritanceInfo = nullptr;
|
||||
|
||||
extern FILE* logfile;
|
||||
fprintf(logfile, "begin\n");
|
||||
fflush(logfile);
|
||||
|
||||
result = vkBeginCommandBuffer(vulkan_demo->command_buffer, &begin_info);
|
||||
check_vk_result(result, "vkBeginCommandBuffer");
|
||||
|
||||
return (const void *)(cmd + 1);
|
||||
}
|
||||
|
||||
|
|
@ -1032,6 +1077,43 @@ const void *RB_SwapBuffers( const void *data ) {
|
|||
|
||||
backEnd.projection2D = qfalse;
|
||||
|
||||
// VULKAN
|
||||
extern FILE* logfile;
|
||||
fprintf(logfile, "present\n");
|
||||
fflush(logfile);
|
||||
|
||||
VkResult result = vkEndCommandBuffer(vulkan_demo->command_buffer);
|
||||
check_vk_result(result, "vkEndCommandBuffer");
|
||||
|
||||
VkPipelineStageFlags wait_dst_stage_mask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
|
||||
VkSubmitInfo submit_info;
|
||||
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
submit_info.pNext = nullptr;
|
||||
submit_info.waitSemaphoreCount = 1;
|
||||
submit_info.pWaitSemaphores = &vulkan_demo->image_acquired;
|
||||
submit_info.pWaitDstStageMask = &wait_dst_stage_mask;
|
||||
submit_info.commandBufferCount = 1;
|
||||
submit_info.pCommandBuffers = &vulkan_demo->command_buffer;
|
||||
submit_info.signalSemaphoreCount = 1;
|
||||
submit_info.pSignalSemaphores = &vulkan_demo->rendering_finished;
|
||||
|
||||
result = vkQueueSubmit(get_queue(), 1, &submit_info, vulkan_demo->rendering_finished_fence);
|
||||
check_vk_result(result, "vkQueueSubmit");
|
||||
|
||||
VkSwapchainKHR swapchain = get_swapchain();
|
||||
VkPresentInfoKHR present_info;
|
||||
present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||
present_info.pNext = nullptr;
|
||||
present_info.waitSemaphoreCount = 1;
|
||||
present_info.pWaitSemaphores = &vulkan_demo->rendering_finished;
|
||||
present_info.swapchainCount = 1;
|
||||
present_info.pSwapchains = &swapchain;
|
||||
present_info.pImageIndices = &vulkan_demo->swapchain_image_index;
|
||||
present_info.pResults = nullptr;
|
||||
result = vkQueuePresentKHR(get_queue(), &present_info);
|
||||
check_vk_result(result, "vkQueuePresentKHR");
|
||||
|
||||
return (const void *)(cmd + 1);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -397,7 +397,4 @@ void RE_RenderScene( const refdef_t *fd ) {
|
|||
r_firstScenePoly = r_numpolys;
|
||||
|
||||
tr.frontEndMsec += ri.Milliseconds() - startTime;
|
||||
|
||||
// VULKAN
|
||||
vulkan_demo->run_frame();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,6 +101,8 @@ static VkFormat find_depth_format(VkPhysicalDevice physical_device) {
|
|||
VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
||||
}
|
||||
|
||||
FILE* logfile;
|
||||
|
||||
Vulkan_Demo::Vulkan_Demo(int window_width, int window_height, const SDL_SysWMinfo& window_sys_info)
|
||||
: window_width(window_width)
|
||||
, window_height(window_height)
|
||||
|
|
@ -110,6 +112,8 @@ Vulkan_Demo::Vulkan_Demo(int window_width, int window_height, const SDL_SysWMinf
|
|||
get_resource_manager()->initialize(get_device());
|
||||
create_command_pool();
|
||||
|
||||
logfile = fopen("debuglog.txt", "w");
|
||||
|
||||
image_acquired = get_resource_manager()->create_semaphore();
|
||||
rendering_finished = get_resource_manager()->create_semaphore();
|
||||
|
||||
|
|
@ -135,17 +139,7 @@ Vulkan_Demo::Vulkan_Demo(int window_width, int window_height, const SDL_SysWMinf
|
|||
create_pipeline();
|
||||
|
||||
upload_geometry();
|
||||
|
||||
{
|
||||
VkCommandBufferAllocateInfo alloc_info;
|
||||
alloc_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||
alloc_info.pNext = nullptr;
|
||||
alloc_info.commandPool = command_pool;
|
||||
alloc_info.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY;
|
||||
alloc_info.commandBufferCount = 1;
|
||||
result = vkAllocateCommandBuffers(get_device(), &alloc_info, &render_scene_command_buffer);
|
||||
check_vk_result(result, "vkAllocateCommandBuffers");
|
||||
}
|
||||
update_ubo_descriptor();
|
||||
|
||||
{
|
||||
VkCommandBufferAllocateInfo alloc_info;
|
||||
|
|
@ -153,9 +147,8 @@ Vulkan_Demo::Vulkan_Demo(int window_width, int window_height, const SDL_SysWMinf
|
|||
alloc_info.pNext = nullptr;
|
||||
alloc_info.commandPool = command_pool;
|
||||
alloc_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||
alloc_info.commandBufferCount = static_cast<uint32_t>(get_swapchain_image_views().size());
|
||||
render_frame_command_buffers.resize(get_swapchain_image_views().size());
|
||||
result = vkAllocateCommandBuffers(get_device(), &alloc_info, render_frame_command_buffers.data());
|
||||
alloc_info.commandBufferCount = 1;
|
||||
result = vkAllocateCommandBuffers(get_device(), &alloc_info, &command_buffer);
|
||||
check_vk_result(result, "vkAllocateCommandBuffers");
|
||||
}
|
||||
}
|
||||
|
|
@ -482,7 +475,7 @@ void Vulkan_Demo::create_pipeline() {
|
|||
rasterization_state.depthClampEnable = VK_FALSE;
|
||||
rasterization_state.rasterizerDiscardEnable = VK_FALSE;
|
||||
rasterization_state.polygonMode = VK_POLYGON_MODE_FILL;
|
||||
rasterization_state.cullMode = VK_CULL_MODE_BACK_BIT;
|
||||
rasterization_state.cullMode = VK_CULL_MODE_NONE/*VK_CULL_MODE_BACK_BIT*/;
|
||||
rasterization_state.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
|
||||
rasterization_state.depthBiasEnable = VK_FALSE;
|
||||
rasterization_state.depthBiasConstantFactor = 0.0f;
|
||||
|
|
@ -600,57 +593,12 @@ void Vulkan_Demo::upload_geometry() {
|
|||
}
|
||||
}
|
||||
|
||||
void Vulkan_Demo::record_render_scene() {
|
||||
VkCommandBufferInheritanceInfo inheritance_info;
|
||||
inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
|
||||
inheritance_info.pNext = nullptr;
|
||||
inheritance_info.renderPass = render_pass;
|
||||
inheritance_info.subpass = 0;
|
||||
inheritance_info.framebuffer = VK_NULL_HANDLE;
|
||||
inheritance_info.occlusionQueryEnable = VK_FALSE;
|
||||
inheritance_info.queryFlags = 0;
|
||||
inheritance_info.pipelineStatistics = 0;
|
||||
|
||||
VkCommandBufferBeginInfo begin_info;
|
||||
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
begin_info.pNext = nullptr;
|
||||
begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT | VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT | VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
|
||||
begin_info.pInheritanceInfo = &inheritance_info;
|
||||
|
||||
VkResult result = vkBeginCommandBuffer(render_scene_command_buffer, &begin_info);
|
||||
check_vk_result(result, "vkBeginCommandBuffer");
|
||||
|
||||
const VkDeviceSize offset = 0;
|
||||
vkCmdBindVertexBuffers(render_scene_command_buffer, 0, 1, &vertex_buffer, &offset);
|
||||
vkCmdBindIndexBuffer(render_scene_command_buffer, index_buffer, 0, VK_INDEX_TYPE_UINT32);
|
||||
vkCmdBindDescriptorSets(render_scene_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &descriptor_set, 0, nullptr);
|
||||
vkCmdBindPipeline(render_scene_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
||||
vkCmdDrawIndexed(render_scene_command_buffer, model_indices_count, 1, 0, 0, 0);
|
||||
|
||||
result = vkEndCommandBuffer(render_scene_command_buffer);
|
||||
check_vk_result(result, "vkEndCommandBuffer");
|
||||
}
|
||||
|
||||
void Vulkan_Demo::record_render_frame() {
|
||||
VkCommandBufferBeginInfo begin_info;
|
||||
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||
begin_info.pNext = nullptr;
|
||||
begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||
begin_info.pInheritanceInfo = nullptr;
|
||||
|
||||
std::array<VkClearValue, 2> clear_values;
|
||||
clear_values[0].color = {0.3f, 0.2f, 0.1f, 0.0f};
|
||||
clear_values[1].depthStencil = {1.0, 0};
|
||||
|
||||
VkRenderPassBeginInfo render_pass_begin_info;
|
||||
render_pass_begin_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||
render_pass_begin_info.pNext = nullptr;
|
||||
render_pass_begin_info.renderPass = render_pass;
|
||||
render_pass_begin_info.framebuffer = VK_NULL_HANDLE; // will be initialized later in the recording loop
|
||||
render_pass_begin_info.renderArea.offset = {0, 0};
|
||||
render_pass_begin_info.renderArea.extent = {(uint32_t)window_width, (uint32_t)window_height};
|
||||
render_pass_begin_info.clearValueCount = static_cast<uint32_t>(clear_values.size());
|
||||
render_pass_begin_info.pClearValues = clear_values.data();
|
||||
VkBufferCopy region;
|
||||
region.srcOffset = 0;
|
||||
region.dstOffset = 0;
|
||||
region.size = sizeof(Uniform_Buffer_Object);
|
||||
vkCmdCopyBuffer(command_buffer, uniform_staging_buffer, uniform_buffer, 1, ®ion);
|
||||
|
||||
VkBufferMemoryBarrier barrier;
|
||||
barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
|
||||
|
|
@ -663,51 +611,42 @@ void Vulkan_Demo::record_render_frame() {
|
|||
barrier.offset = 0;
|
||||
barrier.size = sizeof(Uniform_Buffer_Object);
|
||||
|
||||
for (std::size_t i = 0; i < render_frame_command_buffers.size(); i++) {
|
||||
VkResult result = vkBeginCommandBuffer(render_frame_command_buffers[i], &begin_info);
|
||||
check_vk_result(result, "vkBeginCommandBuffer");
|
||||
vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0,
|
||||
0, nullptr, 1, &barrier, 0, nullptr);
|
||||
|
||||
VkBufferCopy region;
|
||||
region.srcOffset = 0;
|
||||
region.dstOffset = 0;
|
||||
region.size = sizeof(Uniform_Buffer_Object);
|
||||
vkCmdCopyBuffer(render_frame_command_buffers[i], uniform_staging_buffer, uniform_buffer, 1, ®ion);
|
||||
std::array<VkClearValue, 2> clear_values;
|
||||
clear_values[0].color = {0.3f, 0.2f, 0.1f, 0.0f};
|
||||
clear_values[1].depthStencil = {1.0, 0};
|
||||
|
||||
vkCmdPipelineBarrier(render_frame_command_buffers[i], VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, 0,
|
||||
0, nullptr, 1, &barrier, 0, nullptr);
|
||||
VkRenderPassBeginInfo render_pass_begin_info;
|
||||
render_pass_begin_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||
render_pass_begin_info.pNext = nullptr;
|
||||
render_pass_begin_info.renderPass = render_pass;
|
||||
render_pass_begin_info.framebuffer = framebuffers[swapchain_image_index];
|
||||
render_pass_begin_info.renderArea.offset = {0, 0};
|
||||
render_pass_begin_info.renderArea.extent = {(uint32_t)window_width, (uint32_t)window_height};
|
||||
render_pass_begin_info.clearValueCount = static_cast<uint32_t>(clear_values.size());
|
||||
render_pass_begin_info.pClearValues = clear_values.data();
|
||||
|
||||
render_pass_begin_info.framebuffer = framebuffers[i];
|
||||
vkCmdBeginRenderPass(render_frame_command_buffers[i], &render_pass_begin_info, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
|
||||
vkCmdExecuteCommands(render_frame_command_buffers[i], 1, &render_scene_command_buffer);
|
||||
vkCmdEndRenderPass(render_frame_command_buffers[i]);
|
||||
vkCmdBeginRenderPass(command_buffer, &render_pass_begin_info, VK_SUBPASS_CONTENTS_INLINE);
|
||||
|
||||
result = vkEndCommandBuffer(render_frame_command_buffers[i]);
|
||||
check_vk_result(result, "vkEndCommandBuffer");
|
||||
}
|
||||
const VkDeviceSize offset = 0;
|
||||
vkCmdBindVertexBuffers(command_buffer, 0, 1, &vertex_buffer, &offset);
|
||||
vkCmdBindIndexBuffer(command_buffer, index_buffer, 0, VK_INDEX_TYPE_UINT32);
|
||||
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &descriptor_set, 0, nullptr);
|
||||
vkCmdBindPipeline(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
||||
vkCmdDrawIndexed(command_buffer, model_indices_count, 1, 0, 0, 0);
|
||||
|
||||
vkCmdEndRenderPass(command_buffer);
|
||||
}
|
||||
|
||||
void Vulkan_Demo::update_descriptor_set() {
|
||||
static auto start_time = std::chrono::high_resolution_clock::now();
|
||||
auto current_time = std::chrono::high_resolution_clock::now();
|
||||
int time = std::chrono::duration_cast<std::chrono::milliseconds>(current_time - start_time).count();
|
||||
static int image_index = 0;
|
||||
|
||||
if (time > 500) {
|
||||
start_time = current_time;
|
||||
image_index = 37 + (image_index + 1) % (tr.numImages - 37);
|
||||
}
|
||||
|
||||
void Vulkan_Demo::update_ubo_descriptor() {
|
||||
VkDescriptorBufferInfo buffer_info;
|
||||
buffer_info.buffer = uniform_buffer;
|
||||
buffer_info.offset = 0;
|
||||
buffer_info.range = sizeof(Uniform_Buffer_Object);
|
||||
|
||||
VkDescriptorImageInfo image_info;
|
||||
image_info.sampler = texture_image_sampler;
|
||||
image_info.imageView = tr.images[image_index]->vk_image_view;
|
||||
image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
|
||||
std::array<VkWriteDescriptorSet, 2> descriptor_writes;
|
||||
std::array<VkWriteDescriptorSet, 1> descriptor_writes;
|
||||
descriptor_writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
descriptor_writes[0].pNext = nullptr;
|
||||
descriptor_writes[0].dstSet = descriptor_set;
|
||||
|
|
@ -719,26 +658,53 @@ void Vulkan_Demo::update_descriptor_set() {
|
|||
descriptor_writes[0].pBufferInfo = &buffer_info;
|
||||
descriptor_writes[0].pTexelBufferView = nullptr;
|
||||
|
||||
descriptor_writes[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
descriptor_writes[1].dstSet = descriptor_set;
|
||||
descriptor_writes[1].dstBinding = 1;
|
||||
descriptor_writes[1].dstArrayElement = 0;
|
||||
descriptor_writes[1].descriptorCount = 1;
|
||||
descriptor_writes[1].pNext = nullptr;
|
||||
descriptor_writes[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
descriptor_writes[1].pImageInfo = &image_info;
|
||||
descriptor_writes[1].pBufferInfo = nullptr;
|
||||
descriptor_writes[1].pTexelBufferView = nullptr;
|
||||
vkUpdateDescriptorSets(get_device(), (uint32_t)descriptor_writes.size(), descriptor_writes.data(), 0, nullptr);
|
||||
}
|
||||
|
||||
void Vulkan_Demo::update_image_descriptor(bool cinematic) {
|
||||
VkImageView image_view;
|
||||
|
||||
if (cinematic) {
|
||||
image_view = cinematic_image_view;
|
||||
} else {
|
||||
static auto start_time = std::chrono::high_resolution_clock::now();
|
||||
auto current_time = std::chrono::high_resolution_clock::now();
|
||||
int time = std::chrono::duration_cast<std::chrono::milliseconds>(current_time - start_time).count();
|
||||
static int image_index = 0;
|
||||
|
||||
if (time > 200) {
|
||||
start_time = current_time;
|
||||
image_index = (image_index + 1) % tr.numImages;
|
||||
}
|
||||
image_view = tr.images[image_index]->vk_image_view;
|
||||
}
|
||||
|
||||
VkDescriptorImageInfo image_info;
|
||||
image_info.sampler = texture_image_sampler;
|
||||
image_info.imageView = image_view;
|
||||
image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
|
||||
std::array<VkWriteDescriptorSet, 1> descriptor_writes;
|
||||
descriptor_writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||
descriptor_writes[0].dstSet = descriptor_set;
|
||||
descriptor_writes[0].dstBinding = 1;
|
||||
descriptor_writes[0].dstArrayElement = 0;
|
||||
descriptor_writes[0].descriptorCount = 1;
|
||||
descriptor_writes[0].pNext = nullptr;
|
||||
descriptor_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||
descriptor_writes[0].pImageInfo = &image_info;
|
||||
descriptor_writes[0].pBufferInfo = nullptr;
|
||||
descriptor_writes[0].pTexelBufferView = nullptr;
|
||||
|
||||
vkUpdateDescriptorSets(get_device(), (uint32_t)descriptor_writes.size(), descriptor_writes.data(), 0, nullptr);
|
||||
}
|
||||
|
||||
void Vulkan_Demo::update_uniform_buffer() {
|
||||
void Vulkan_Demo::update_uniform_buffer(bool cinematic) {
|
||||
static auto start_time = std::chrono::high_resolution_clock::now();
|
||||
|
||||
auto current_time = std::chrono::high_resolution_clock::now();
|
||||
float time = std::chrono::duration_cast<std::chrono::milliseconds>(current_time - start_time).count() / 1000.f;
|
||||
time = 0.0;
|
||||
if (cinematic) time = 0.0;
|
||||
|
||||
Uniform_Buffer_Object ubo;
|
||||
ubo.model = glm::rotate(glm::mat4(), time * glm::radians(30.0f), glm::vec3(0, 1, 0));
|
||||
|
|
@ -761,48 +727,20 @@ void Vulkan_Demo::update_uniform_buffer() {
|
|||
vkUnmapMemory(get_device(), uniform_staging_buffer_memory);
|
||||
}
|
||||
|
||||
void Vulkan_Demo::run_frame() {
|
||||
VkResult result = vkWaitForFences(get_device(), 1, &rendering_finished_fence, VK_FALSE, 1e9);
|
||||
check_vk_result(result, "vkWaitForFences");
|
||||
result = vkResetFences(get_device(), 1, &rendering_finished_fence);
|
||||
check_vk_result(result, "vkResetFences");
|
||||
update_descriptor_set();
|
||||
record_render_scene(); // record secondary command buffer before primary ones
|
||||
void Vulkan_Demo::render_view() {
|
||||
fprintf(logfile, "render_view\n");
|
||||
fflush(logfile);
|
||||
|
||||
update_image_descriptor(false);
|
||||
record_render_frame();
|
||||
|
||||
update_uniform_buffer();
|
||||
|
||||
uint32_t swapchain_image_index;
|
||||
result = vkAcquireNextImageKHR(get_device(), get_swapchain(), UINT64_MAX, image_acquired, VK_NULL_HANDLE, &swapchain_image_index);
|
||||
check_vk_result(result, "vkAcquireNextImageKHR");
|
||||
|
||||
VkPipelineStageFlags wait_dst_stage_mask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||
|
||||
VkSubmitInfo submit_info;
|
||||
submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||
submit_info.pNext = nullptr;
|
||||
submit_info.waitSemaphoreCount = 1;
|
||||
submit_info.pWaitSemaphores = &image_acquired;
|
||||
submit_info.pWaitDstStageMask = &wait_dst_stage_mask;
|
||||
submit_info.commandBufferCount = 1;
|
||||
submit_info.pCommandBuffers = &render_frame_command_buffers[swapchain_image_index];
|
||||
submit_info.signalSemaphoreCount = 1;
|
||||
submit_info.pSignalSemaphores = &rendering_finished;
|
||||
|
||||
result = vkQueueSubmit(get_queue(), 1, &submit_info, rendering_finished_fence);
|
||||
check_vk_result(result, "vkQueueSubmit");
|
||||
|
||||
VkSwapchainKHR swapchain = get_swapchain();
|
||||
VkPresentInfoKHR present_info;
|
||||
present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||
present_info.pNext = nullptr;
|
||||
present_info.waitSemaphoreCount = 1;
|
||||
present_info.pWaitSemaphores = &rendering_finished;
|
||||
present_info.swapchainCount = 1;
|
||||
present_info.pSwapchains = &swapchain;
|
||||
present_info.pImageIndices = &swapchain_image_index;
|
||||
present_info.pResults = nullptr;
|
||||
|
||||
result = vkQueuePresentKHR(get_queue(), &present_info);
|
||||
check_vk_result(result, "vkQueuePresentKHR");
|
||||
update_uniform_buffer(false);
|
||||
}
|
||||
|
||||
void Vulkan_Demo::render_cinematic_frame() {
|
||||
fprintf(logfile, "render_cinematic_frame\n");
|
||||
fflush(logfile);
|
||||
|
||||
update_image_descriptor(true);
|
||||
record_render_frame();
|
||||
update_uniform_buffer(true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ public:
|
|||
Vulkan_Demo(int window_width, int window_height, const SDL_SysWMinfo& window_sys_info);
|
||||
~Vulkan_Demo();
|
||||
|
||||
void run_frame();
|
||||
void render_view();
|
||||
void render_cinematic_frame();
|
||||
|
||||
public:
|
||||
void create_command_pool();
|
||||
|
|
@ -30,12 +31,12 @@ public:
|
|||
void create_pipeline();
|
||||
|
||||
void upload_geometry();
|
||||
void record_render_scene();
|
||||
void record_render_frame();
|
||||
void update_descriptor_set();
|
||||
void update_uniform_buffer();
|
||||
void update_ubo_descriptor();
|
||||
void update_image_descriptor(bool cinematic);
|
||||
void update_uniform_buffer(bool cinematic);
|
||||
|
||||
private:
|
||||
public:
|
||||
const int window_width = 0;
|
||||
const int window_height = 0;
|
||||
|
||||
|
|
@ -65,6 +66,8 @@ private:
|
|||
VkBuffer index_buffer = VK_NULL_HANDLE;
|
||||
uint32_t model_indices_count = 0;
|
||||
|
||||
std::vector<VkCommandBuffer> render_frame_command_buffers; // command buffer per swapchain image
|
||||
VkCommandBuffer render_scene_command_buffer;
|
||||
VkCommandBuffer command_buffer = VK_NULL_HANDLE;
|
||||
|
||||
uint32_t swapchain_image_index = -1;
|
||||
VkImageView cinematic_image_view = VK_NULL_HANDLE;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user