화면크기변경 로직 추가

This commit is contained in:
2025-05-17 20:13:34 +09:00
parent bba916f29e
commit 45ee4f0056
12 changed files with 308 additions and 127 deletions

View File

@@ -38,6 +38,14 @@ FetchContent_Declare(
) )
FetchContent_MakeAvailable(GSL) FetchContent_MakeAvailable(GSL)
FetchContent_Declare(
ASSIMP
GIT_REPOSITORY "https://github.com/assimp/assimp.git"
GIT_TAG "v5.4.3"
GIT_SHALLOW ON
)
FetchContent_MakeAvailable(ASSIMP)
file(GLOB_RECURSE VulkanEngineSources CONFIGURE_DEPENDS file(GLOB_RECURSE VulkanEngineSources CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/glfw/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/glfw/*.cpp"
@@ -50,6 +58,7 @@ target_link_libraries(VulkanEngine PRIVATE glm)
target_link_libraries(VulkanEngine PRIVATE glfw) target_link_libraries(VulkanEngine PRIVATE glfw)
target_link_libraries(VulkanEngine PRIVATE Microsoft.GSL::GSL) target_link_libraries(VulkanEngine PRIVATE Microsoft.GSL::GSL)
target_link_libraries(VulkanEngine PRIVATE spdlog) target_link_libraries(VulkanEngine PRIVATE spdlog)
target_link_libraries(VulkanEngine PRIVATE assimp::assimp)
target_include_directories(VulkanEngine PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/include") target_include_directories(VulkanEngine PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/include")
target_compile_features(VulkanEngine PRIVATE cxx_std_20) target_compile_features(VulkanEngine PRIVATE cxx_std_20)
@@ -64,4 +73,5 @@ file(GLOB_RECURSE ShaderSources CONFIGURE_DEPENDS
add_shaders(VulkanEngineShaders ${ShaderSources}) add_shaders(VulkanEngineShaders ${ShaderSources})
add_dependencies(VulkanEngine VulkanEngineShaders) add_dependencies(VulkanEngine VulkanEngineShaders)
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/assets/paving-stones.jpg" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/assets") file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/assets/paving-stones.jpg" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/assets")
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/assets/player.fbx" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/assets")

BIN
assets/player.fbx Normal file

Binary file not shown.

View File

@@ -12,3 +12,5 @@
#include "spdlog/spdlog.h" #include "spdlog/spdlog.h"
#include "utilities.h" #include "utilities.h"
#define MAX_BUFFERED_FRAMES (2)

View File

@@ -8,6 +8,19 @@
#include "vertex.h" #include "vertex.h"
namespace veng { namespace veng {
struct Frame {
VkSemaphore image_available_signal = VK_NULL_HANDLE;
VkSemaphore render_finished_signal = VK_NULL_HANDLE;
VkFence still_rendering_fence = VK_NULL_HANDLE;
VkCommandBuffer command_buffer = VK_NULL_HANDLE;
VkDescriptorSet uniform_set = VK_NULL_HANDLE;
BufferHandle uniform_buffer;
void* uniform_buffer_location;
};
class Graphics final { class Graphics final {
public: public:
Graphics(gsl::not_null<Window*> window); Graphics(gsl::not_null<Window*> window);
@@ -66,6 +79,7 @@ class Graphics final {
void CreateDescriptorPools(); void CreateDescriptorPools();
void CreateDescriptorSets(); void CreateDescriptorSets();
void CreateTextureSampler(); void CreateTextureSampler();
void CreateDepthResources();
void RecreateSwapChain(); void RecreateSwapChain();
void CleanupSwapChain(); void CleanupSwapChain();
@@ -111,11 +125,14 @@ class Graphics final {
void EndTransientCommandBuffer(VkCommandBuffer command_buffer); void EndTransientCommandBuffer(VkCommandBuffer command_buffer);
void CreateUniformBuffers(); void CreateUniformBuffers();
TextureHandle CreateImage(glm::ivec2 size, VkBufferUsageFlags usage, TextureHandle CreateImage(glm::ivec2 size, VkFormat image_format,
VkBufferUsageFlags usage,
VkMemoryPropertyFlags properties); VkMemoryPropertyFlags properties);
void TransitionImageLayout(VkImage image, VkImageLayout old_layout, VkImageLayout new_layout); void TransitionImageLayout(VkImage image, VkImageLayout old_layout,
VkImageLayout new_layout);
void CopyBufferToImage(VkBuffer buffer, VkImage image, glm::ivec2 image_size); void CopyBufferToImage(VkBuffer buffer, VkImage image, glm::ivec2 image_size);
VkImageView CreateImageView(VkImage image, VkFormat format); VkImageView CreateImageView(VkImage image, VkFormat format,
VkImageAspectFlags aspect_flag);
VkViewport GetViewport(); VkViewport GetViewport();
VkRect2D GetScissor(); VkRect2D GetScissor();
@@ -147,23 +164,20 @@ class Graphics final {
VkDescriptorSetLayout descriptor_set_layout_ = VK_NULL_HANDLE; VkDescriptorSetLayout descriptor_set_layout_ = VK_NULL_HANDLE;
VkCommandPool command_pool_ = VK_NULL_HANDLE; VkCommandPool command_pool_ = VK_NULL_HANDLE;
VkCommandBuffer command_buffer_ = VK_NULL_HANDLE;
VkSemaphore image_available_signal_ = VK_NULL_HANDLE;
VkSemaphore render_finished_signal_ = VK_NULL_HANDLE;
VkFence still_rendering_fence_ = VK_NULL_HANDLE;
std::uint32_t current_image_index_ = 0; std::uint32_t current_image_index_ = 0;
VkDescriptorSetLayout uniform_set_layout_ = VK_NULL_HANDLE; VkDescriptorSetLayout uniform_set_layout_ = VK_NULL_HANDLE;
VkDescriptorPool uniform_pool_ = VK_NULL_HANDLE; VkDescriptorPool uniform_pool_ = VK_NULL_HANDLE;
VkDescriptorSet uniform_set_ = VK_NULL_HANDLE;
BufferHandle uniform_buffer_;
void* uniform_buffer_location_;
VkDescriptorSetLayout texture_set_layout_ = VK_NULL_HANDLE; VkDescriptorSetLayout texture_set_layout_ = VK_NULL_HANDLE;
VkDescriptorPool texture_pool_ = VK_NULL_HANDLE; VkDescriptorPool texture_pool_ = VK_NULL_HANDLE;
VkSampler texture_sampler_ = VK_NULL_HANDLE; VkSampler texture_sampler_ = VK_NULL_HANDLE;
TextureHandle depth_texture_;
std::array<Frame, MAX_BUFFERED_FRAMES> frames_;
std::int32_t current_frame_ = 0;
gsl::not_null<Window*> window_; gsl::not_null<Window*> window_;
bool validation_enabled_ = false; bool validation_enabled_ = false;

View File

@@ -1,15 +1,16 @@
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
#include <iostream>
#include "assimp/Importer.hpp"
#include "assimp/postprocess.h"
#include "glfw/glfw_initialization.h" #include "glfw/glfw_initialization.h"
#include "glfw/glfw_monitor.h" #include "glfw/glfw_monitor.h"
#include "glfw/glfw_window.h" #include "glfw/glfw_window.h"
#include "precomp.h" #include "precomp.h"
#include "vulkan/graphics.h" #include "vulkan/graphics.h"
#include <iostream>
std::int32_t main(std::int32_t argc, gsl::zstring* argv) { std::int32_t main(std::int32_t argc, gsl::zstring* argv) {
const veng::GlfwInitialization _glfw; const veng::GlfwInitialization _glfw;
@@ -18,6 +19,17 @@ std::int32_t main(std::int32_t argc, gsl::zstring* argv) {
veng::Graphics graphics(&window); veng::Graphics graphics(&window);
Assimp::Importer assetImporter;
const struct aiScene* scene = assetImporter.ReadFile(
"assets/player.fbx", aiProcess_CalcTangentSpace | aiProcess_Triangulate |
aiProcess_JoinIdenticalVertices | aiProcess_SortByPType);
if (nullptr == scene) {
spdlog::error(assetImporter.GetErrorString());
return false;
}
std::array<veng::Vertex, 4> vertices = { std::array<veng::Vertex, 4> vertices = {
veng::Vertex{{-.5f, -.5f, 0.f}, {0.f, 1.f}}, veng::Vertex{{-.5f, -.5f, 0.f}, {0.f, 1.f}},
veng::Vertex{{.5f, -.5f, 0.f}, {1.f, 1.f}}, veng::Vertex{{.5f, -.5f, 0.f}, {1.f, 1.f}},
@@ -30,28 +42,45 @@ std::int32_t main(std::int32_t argc, gsl::zstring* argv) {
glm::mat4 rotation = glm::rotate(glm::mat4(1.0f), glm::radians(45.f), glm::mat4 rotation = glm::rotate(glm::mat4(1.0f), glm::radians(45.f),
glm::vec3(0.f, 1.f, 0.f)); glm::vec3(0.f, 1.f, 0.f));
glm::mat4 rotation2 =
glm::rotate(glm::mat4(1.0f), glm::radians(0.f), glm::vec3(0.f, 0.f, 1.f));
glm::mat4 view = glm::translate(glm::mat4(1.f), glm::vec3(0.f, 0.f, -2.f)); glm::mat4 view = glm::translate(glm::mat4(1.f), glm::vec3(0.f, 0.f, -2.f));
glm::mat4 projection = glm::mat4 projection =
glm::perspective(glm::radians(60.f), 800.f / 600.f, 0.1f, 100.f); glm::perspective(glm::radians(150.f), 800.f / 600.f, 0.1f, 100.f);
graphics.SetViewProjection(view, projection); graphics.SetViewProjection(view, projection);
veng::TextureHandle texture = graphics.CreateTexture("assets/paving-stones.jpg"); veng::TextureHandle texture =
graphics.CreateTexture("assets/paving-stones.jpg");
double last_time = glfwGetTime(); double last_time = glfwGetTime();
glm::ivec2 window_size;
while (!window.ShouldClose()) { while (!window.ShouldClose()) {
glfwPollEvents(); glfwPollEvents();
glm::ivec2 current_window_size = window.GetFramebufferSize();
if (current_window_size != window_size && current_window_size.x != 0 && current_window_size.y != 0) {
window_size = current_window_size;
projection = glm::perspective(
glm::radians(90.f),
(float)current_window_size.x / (float)current_window_size.y, 0.1f,
100.f);
graphics.SetViewProjection(view, projection);
}
if (graphics.BeginFrame()) { if (graphics.BeginFrame()) {
double current_time = glfwGetTime(); double current_time = glfwGetTime();
float delta_time = static_cast<float>(current_time - last_time); float delta_time = static_cast<float>(current_time - last_time);
last_time = current_time; last_time = current_time;
std::cout << 1.f / delta_time << std::endl;
graphics.SetTexture(texture); graphics.SetTexture(texture);
rotation2 = glm::rotate(rotation2, delta_time * glm::radians(-360.f),
glm::vec3(0.f, 0.f, 1.f));
graphics.SetModelMatrix(rotation2);
graphics.RenderIndexedBuffer(buffer, index_buffer, indices.size()); graphics.RenderIndexedBuffer(buffer, index_buffer, indices.size());
rotation = glm::rotate(rotation, delta_time * glm::radians(3600.f), rotation = glm::rotate(rotation, delta_time * glm::radians(360.f),
glm::vec3(0.f, 0.f, 1.f)); glm::vec3(0.f, 0.f, 1.f));
graphics.SetModelMatrix(rotation); graphics.SetModelMatrix(rotation);
graphics.RenderIndexedBuffer(buffer, index_buffer, indices.size()); graphics.RenderIndexedBuffer(buffer, index_buffer, indices.size());

View File

@@ -134,34 +134,40 @@ void Graphics::DestroyBuffer(BufferHandle handle) {
} }
void Graphics::SetModelMatrix(glm::mat4 model) { void Graphics::SetModelMatrix(glm::mat4 model) {
vkCmdPushConstants(command_buffer_, pipeline_layout_, // for (Frame& frame : frames_)
vkCmdPushConstants(frames_[current_frame_].command_buffer, pipeline_layout_,
VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(glm::mat4), &model); VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(glm::mat4), &model);
} }
void Graphics::SetViewProjection(glm::mat4 view, glm::mat4 projection) { void Graphics::SetViewProjection(glm::mat4 view, glm::mat4 projection) {
UniformTransformations transformations{view, projection}; UniformTransformations transformations{view, projection};
std::memcpy(uniform_buffer_location_, &transformations, for (Frame& frame : frames_)
sizeof(UniformTransformations)); std::memcpy(frame.uniform_buffer_location,
&transformations, sizeof(UniformTransformations));
} }
void Graphics::RenderBuffer(BufferHandle handle, std::uint32_t vertex_count) { void Graphics::RenderBuffer(BufferHandle handle, std::uint32_t vertex_count) {
VkDeviceSize offset = 0; VkDeviceSize offset = 0;
vkCmdBindDescriptorSets(command_buffer_, VK_PIPELINE_BIND_POINT_GRAPHICS, vkCmdBindDescriptorSets(frames_[current_frame_].command_buffer,
pipeline_layout_, 0, 1, &uniform_set_, 0, nullptr); VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout_, 0,
vkCmdBindVertexBuffers(command_buffer_, 0, 1, &handle.buffer, &offset); 1, &frames_[current_frame_].uniform_set, 0, nullptr);
vkCmdDraw(command_buffer_, vertex_count, 1, 0, 0); vkCmdBindVertexBuffers(frames_[current_frame_].command_buffer, 0, 1,
&handle.buffer, &offset);
vkCmdDraw(frames_[current_frame_].command_buffer, vertex_count, 1, 0, 0);
} }
void Graphics::RenderIndexedBuffer(BufferHandle vertex_buffer, void Graphics::RenderIndexedBuffer(BufferHandle vertex_buffer,
BufferHandle index_buffer, BufferHandle index_buffer,
std::uint32_t count) { std::uint32_t count) {
VkDeviceSize offset = 0; VkDeviceSize offset = 0;
vkCmdBindDescriptorSets(command_buffer_, VK_PIPELINE_BIND_POINT_GRAPHICS, vkCmdBindDescriptorSets(frames_[current_frame_].command_buffer,
pipeline_layout_, 0, 1, &uniform_set_, 0, nullptr); VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout_, 0,
vkCmdBindVertexBuffers(command_buffer_, 0, 1, &vertex_buffer.buffer, &offset); 1, &frames_[current_frame_].uniform_set, 0, nullptr);
vkCmdBindIndexBuffer(command_buffer_, index_buffer.buffer, 0, vkCmdBindVertexBuffers(frames_[current_frame_].command_buffer, 0, 1,
VK_INDEX_TYPE_UINT32); &vertex_buffer.buffer, &offset);
vkCmdDrawIndexed(command_buffer_, count, 1, 0, 0, 0); vkCmdBindIndexBuffer(frames_[current_frame_].command_buffer,
index_buffer.buffer, 0, VK_INDEX_TYPE_UINT32);
vkCmdDrawIndexed(frames_[current_frame_].command_buffer, count, 1, 0, 0, 0);
SetModelMatrix(glm::mat4(1.f)); SetModelMatrix(glm::mat4(1.f));
} }
@@ -198,13 +204,15 @@ void Graphics::EndTransientCommandBuffer(VkCommandBuffer command_buffer) {
void Graphics::CreateUniformBuffers() { void Graphics::CreateUniformBuffers() {
VkDeviceSize buffer_size = sizeof(UniformTransformations); VkDeviceSize buffer_size = sizeof(UniformTransformations);
uniform_buffer_ = for (Frame& frame : frames_) {
CreateBuffer(buffer_size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, frame.uniform_buffer =
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | CreateBuffer(buffer_size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
vkMapMemory(logical_device_, uniform_buffer_.memory, 0, buffer_size, 0, vkMapMemory(logical_device_, frame.uniform_buffer.memory, 0, buffer_size, 0,
&uniform_buffer_location_); &frame.uniform_buffer_location);
}
} }
void Graphics::CreateDescriptorSetLayouts() { void Graphics::CreateDescriptorSetLayouts() {
@@ -249,13 +257,13 @@ void Graphics::CreateDescriptorSetLayouts() {
void Graphics::CreateDescriptorPools() { void Graphics::CreateDescriptorPools() {
VkDescriptorPoolSize uniform_pool_size = {}; VkDescriptorPoolSize uniform_pool_size = {};
uniform_pool_size.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; uniform_pool_size.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
uniform_pool_size.descriptorCount = 1; uniform_pool_size.descriptorCount = MAX_BUFFERED_FRAMES;
VkDescriptorPoolCreateInfo uniform_create_info = {}; VkDescriptorPoolCreateInfo uniform_create_info = {};
uniform_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; uniform_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
uniform_create_info.poolSizeCount = 1; uniform_create_info.poolSizeCount = 1;
uniform_create_info.pPoolSizes = &uniform_pool_size; uniform_create_info.pPoolSizes = &uniform_pool_size;
uniform_create_info.maxSets = 1; uniform_create_info.maxSets = MAX_BUFFERED_FRAMES;
if (vkCreateDescriptorPool(logical_device_, &uniform_create_info, nullptr, if (vkCreateDescriptorPool(logical_device_, &uniform_create_info, nullptr,
&uniform_pool_) != VK_SUCCESS) { &uniform_pool_) != VK_SUCCESS) {
@@ -284,31 +292,33 @@ void Graphics::CreateDescriptorPools() {
} }
void Graphics::CreateDescriptorSets() { void Graphics::CreateDescriptorSets() {
VkDescriptorSetAllocateInfo set_info = {}; for (Frame& frame : frames_) {
set_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; VkDescriptorSetAllocateInfo set_info = {};
set_info.descriptorPool = uniform_pool_; set_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
set_info.descriptorSetCount = 1; set_info.descriptorPool = uniform_pool_;
set_info.pSetLayouts = &uniform_set_layout_; set_info.descriptorSetCount = 1;
set_info.pSetLayouts = &uniform_set_layout_;
VkResult result = VkResult result = vkAllocateDescriptorSets(logical_device_, &set_info,
vkAllocateDescriptorSets(logical_device_, &set_info, &uniform_set_); &frame.uniform_set);
if (result != VK_SUCCESS) std::exit(EXIT_FAILURE); if (result != VK_SUCCESS) std::exit(EXIT_FAILURE);
VkDescriptorBufferInfo buffer_info = {}; VkDescriptorBufferInfo buffer_info = {};
buffer_info.buffer = uniform_buffer_.buffer; buffer_info.buffer = frame.uniform_buffer.buffer;
buffer_info.offset = 0; buffer_info.offset = 0;
buffer_info.range = sizeof(UniformTransformations); buffer_info.range = sizeof(UniformTransformations);
VkWriteDescriptorSet descriptor_write = {}; VkWriteDescriptorSet descriptor_write = {};
descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; descriptor_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
descriptor_write.dstSet = uniform_set_; descriptor_write.dstSet = frame.uniform_set;
descriptor_write.dstBinding = 0; descriptor_write.dstBinding = 0;
descriptor_write.dstArrayElement = 0; descriptor_write.dstArrayElement = 0;
descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; descriptor_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
descriptor_write.descriptorCount = 1; descriptor_write.descriptorCount = 1;
descriptor_write.pBufferInfo = &buffer_info; descriptor_write.pBufferInfo = &buffer_info;
vkUpdateDescriptorSets(logical_device_, 1, &descriptor_write, 0, nullptr); vkUpdateDescriptorSets(logical_device_, 1, &descriptor_write, 0, nullptr);
}
} }
} // namespace veng } // namespace veng

View File

@@ -16,6 +16,7 @@ Graphics::~Graphics() {
if (logical_device_ != VK_NULL_HANDLE) { if (logical_device_ != VK_NULL_HANDLE) {
vkDeviceWaitIdle(logical_device_); vkDeviceWaitIdle(logical_device_);
CleanupSwapChain(); CleanupSwapChain();
DestroyTexture(depth_texture_);
if (texture_pool_ != VK_NULL_HANDLE) if (texture_pool_ != VK_NULL_HANDLE)
vkDestroyDescriptorPool(logical_device_, texture_pool_, nullptr); vkDestroyDescriptorPool(logical_device_, texture_pool_, nullptr);
@@ -30,21 +31,25 @@ Graphics::~Graphics() {
if (uniform_pool_ != VK_NULL_HANDLE) if (uniform_pool_ != VK_NULL_HANDLE)
vkDestroyDescriptorPool(logical_device_, uniform_pool_, nullptr); vkDestroyDescriptorPool(logical_device_, uniform_pool_, nullptr);
DestroyBuffer(uniform_buffer_); for (Frame& frame : frames_) {
DestroyBuffer(frame.uniform_buffer);
if (frame.image_available_signal != VK_NULL_HANDLE)
vkDestroySemaphore(logical_device_, frame.image_available_signal,
nullptr);
if (frame.render_finished_signal != VK_NULL_HANDLE)
vkDestroySemaphore(logical_device_, frame.render_finished_signal,
nullptr);
if (frame.still_rendering_fence != VK_NULL_HANDLE)
vkDestroyFence(logical_device_, frame.still_rendering_fence, nullptr);
}
if (uniform_set_layout_ != VK_NULL_HANDLE) if (uniform_set_layout_ != VK_NULL_HANDLE)
vkDestroyDescriptorSetLayout(logical_device_, uniform_set_layout_, vkDestroyDescriptorSetLayout(logical_device_, uniform_set_layout_,
nullptr); nullptr);
if (image_available_signal_ != VK_NULL_HANDLE)
vkDestroySemaphore(logical_device_, image_available_signal_, nullptr);
if (render_finished_signal_ != VK_NULL_HANDLE)
vkDestroySemaphore(logical_device_, render_finished_signal_, nullptr);
if (still_rendering_fence_ != VK_NULL_HANDLE)
vkDestroyFence(logical_device_, still_rendering_fence_, nullptr);
if (command_pool_ != VK_NULL_HANDLE) if (command_pool_ != VK_NULL_HANDLE)
vkDestroyCommandPool(logical_device_, command_pool_, nullptr); vkDestroyCommandPool(logical_device_, command_pool_, nullptr);
@@ -81,6 +86,7 @@ void Graphics::InitializeVulkan() {
CreateRenderPass(); CreateRenderPass();
CreateDescriptorSetLayouts(); CreateDescriptorSetLayouts();
CreateGraphicsPipeline(); CreateGraphicsPipeline();
CreateDepthResources();
CreateFramebuffers(); CreateFramebuffers();
CreateCommandPool(); CreateCommandPool();
CreateCommandBuffer(); CreateCommandBuffer();
@@ -89,6 +95,8 @@ void Graphics::InitializeVulkan() {
CreateDescriptorPools(); CreateDescriptorPools();
CreateDescriptorSets(); CreateDescriptorSets();
CreateTextureSampler(); CreateTextureSampler();
TransitionImageLayout(depth_texture_.image, VK_IMAGE_LAYOUT_UNDEFINED,
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
} }
} // namespace veng } // namespace veng

View File

@@ -140,6 +140,8 @@ void Graphics::CreateLogicalDeviceAndQueues() {
} }
VkPhysicalDeviceFeatures required_features = {}; VkPhysicalDeviceFeatures required_features = {};
required_features.depthBounds = true;
required_features.depthClamp = true;
VkDeviceCreateInfo device_info = {}; VkDeviceCreateInfo device_info = {};
device_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; device_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;

View File

@@ -9,11 +9,14 @@ void Graphics::CreateFramebuffers() {
swap_chain_framebuffers_.resize(swap_chain_image_views_.size()); swap_chain_framebuffers_.resize(swap_chain_image_views_.size());
for (std::uint32_t i = 0; i < swap_chain_image_views_.size(); i++) { for (std::uint32_t i = 0; i < swap_chain_image_views_.size(); i++) {
std::array<VkImageView, 2> attachments = {swap_chain_image_views_[i],
depth_texture_.image_view};
VkFramebufferCreateInfo info = {}; VkFramebufferCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
info.renderPass = render_pass_; info.renderPass = render_pass_;
info.attachmentCount = 1; info.attachmentCount = attachments.size();
info.pAttachments = &swap_chain_image_views_[i]; info.pAttachments = attachments.data();
info.width = extent_.width; info.width = extent_.width;
info.height = extent_.height; info.height = extent_.height;
info.layers = 1; info.layers = 1;
@@ -43,21 +46,28 @@ void Graphics::CreateCommandBuffer() {
info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
info.commandBufferCount = 1; info.commandBufferCount = 1;
VkResult result = for (Frame& frame : frames_) {
vkAllocateCommandBuffers(logical_device_, &info, &command_buffer_); VkResult result =
if (result != VK_SUCCESS) std::exit(EXIT_FAILURE); vkAllocateCommandBuffers(logical_device_, &info, &frame.command_buffer);
if (result != VK_SUCCESS) std::exit(EXIT_FAILURE);
}
} }
void Graphics::BeginCommands() { void Graphics::BeginCommands() {
vkResetCommandBuffer(command_buffer_, 0); vkResetCommandBuffer(frames_[current_frame_].command_buffer, 0);
VkCommandBufferBeginInfo begin_info = {}; VkCommandBufferBeginInfo begin_info = {};
begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
VkResult result = vkBeginCommandBuffer(command_buffer_, &begin_info); VkResult result = vkBeginCommandBuffer(
frames_[current_frame_].command_buffer, &begin_info);
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
throw std::runtime_error("Failed to begin command buffer!"); throw std::runtime_error("Failed to begin command buffer!");
std::array<VkClearValue, 2> clear_values;
clear_values[0].color = {{0.f, 0.f, 0.f, 1.f}};
clear_values[1].depthStencil = {1.f, 0};
VkRenderPassBeginInfo render_pass_begin_info = {}; VkRenderPassBeginInfo render_pass_begin_info = {};
render_pass_begin_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; render_pass_begin_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
render_pass_begin_info.renderPass = render_pass_; render_pass_begin_info.renderPass = render_pass_;
@@ -65,54 +75,60 @@ void Graphics::BeginCommands() {
swap_chain_framebuffers_[current_image_index_]; swap_chain_framebuffers_[current_image_index_];
render_pass_begin_info.renderArea.offset = {0, 0}; render_pass_begin_info.renderArea.offset = {0, 0};
render_pass_begin_info.renderArea.extent = extent_; render_pass_begin_info.renderArea.extent = extent_;
render_pass_begin_info.clearValueCount = clear_values.size();
render_pass_begin_info.pClearValues = clear_values.data();
VkClearValue clear_color = {{{0.f, 0.f, 0.f, 1.f}}}; vkCmdBeginRenderPass(frames_[current_frame_].command_buffer,
render_pass_begin_info.clearValueCount = 1; &render_pass_begin_info,
render_pass_begin_info.pClearValues = &clear_color;
vkCmdBeginRenderPass(command_buffer_, &render_pass_begin_info,
VK_SUBPASS_CONTENTS_INLINE); VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindPipeline(command_buffer_, VK_PIPELINE_BIND_POINT_GRAPHICS, vkCmdBindPipeline(frames_[current_frame_].command_buffer,
VK_PIPELINE_BIND_POINT_GRAPHICS,
pipeline_); pipeline_);
VkViewport viewport = GetViewport(); VkViewport viewport = GetViewport();
VkRect2D scissor = GetScissor(); VkRect2D scissor = GetScissor();
vkCmdSetViewport(command_buffer_, 0, 1, &viewport); vkCmdSetViewport(frames_[current_frame_].command_buffer, 0, 1, &viewport);
vkCmdSetScissor(command_buffer_, 0, 1, &scissor); vkCmdSetScissor(frames_[current_frame_].command_buffer, 0, 1, &scissor);
} }
void Graphics::EndCommands() { void Graphics::EndCommands() {
vkCmdEndRenderPass(command_buffer_); vkCmdEndRenderPass(frames_[current_frame_].command_buffer);
VkResult result = vkEndCommandBuffer(command_buffer_); VkResult result = vkEndCommandBuffer(frames_[current_frame_].command_buffer);
if (result != VK_SUCCESS) if (result != VK_SUCCESS)
throw std::runtime_error("Failed to record command buffer!"); throw std::runtime_error("Failed to record command buffer!");
} }
void Graphics::CreateSignals() { void Graphics::CreateSignals() {
VkSemaphoreCreateInfo semafore_info = {}; for (Frame& frame : frames_) {
semafore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; VkSemaphoreCreateInfo semafore_info = {};
semafore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
if (vkCreateSemaphore(logical_device_, &semafore_info, nullptr, if (vkCreateSemaphore(logical_device_, &semafore_info, nullptr,
&image_available_signal_) != VK_SUCCESS) &frame.image_available_signal) !=
std::exit(EXIT_FAILURE); VK_SUCCESS)
if (vkCreateSemaphore(logical_device_, &semafore_info, nullptr, std::exit(EXIT_FAILURE);
&render_finished_signal_) != VK_SUCCESS) if (vkCreateSemaphore(logical_device_, &semafore_info, nullptr,
std::exit(EXIT_FAILURE); &frame.render_finished_signal) !=
VK_SUCCESS)
std::exit(EXIT_FAILURE);
VkFenceCreateInfo fence_info = {}; VkFenceCreateInfo fence_info = {};
fence_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; fence_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fence_info.flags = VK_FENCE_CREATE_SIGNALED_BIT; fence_info.flags = VK_FENCE_CREATE_SIGNALED_BIT;
if (vkCreateFence(logical_device_, &fence_info, nullptr, if (vkCreateFence(logical_device_, &fence_info, nullptr,
&still_rendering_fence_) != VK_SUCCESS) &frame.still_rendering_fence) !=
std::exit(EXIT_FAILURE); VK_SUCCESS)
std::exit(EXIT_FAILURE);
}
} }
bool Graphics::BeginFrame() { bool Graphics::BeginFrame() {
vkWaitForFences(logical_device_, 1, &still_rendering_fence_, VK_TRUE, vkWaitForFences(logical_device_, 1,
&frames_[current_frame_].still_rendering_fence, VK_TRUE,
UINT64_MAX); UINT64_MAX);
VkResult image_acquire_result = vkAcquireNextImageKHR( VkResult image_acquire_result = vkAcquireNextImageKHR(logical_device_, swap_chain_, UINT64_MAX,
logical_device_, swap_chain_, UINT64_MAX, image_available_signal_, frames_[current_frame_].image_available_signal,
VK_NULL_HANDLE, &current_image_index_); VK_NULL_HANDLE, &current_image_index_);
if (image_acquire_result == VK_ERROR_OUT_OF_DATE_KHR) { if (image_acquire_result == VK_ERROR_OUT_OF_DATE_KHR) {
@@ -124,7 +140,8 @@ bool Graphics::BeginFrame() {
image_acquire_result != VK_SUBOPTIMAL_KHR) image_acquire_result != VK_SUBOPTIMAL_KHR)
throw std::runtime_error("Couldn't acquire render image!"); throw std::runtime_error("Couldn't acquire render image!");
vkResetFences(logical_device_, 1, &still_rendering_fence_); vkResetFences(logical_device_, 1,
&frames_[current_frame_].still_rendering_fence);
BeginCommands(); BeginCommands();
SetModelMatrix(glm::mat4(1.f)); SetModelMatrix(glm::mat4(1.f));
@@ -139,22 +156,25 @@ void veng::Graphics::EndFrame() {
VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
submit_info.waitSemaphoreCount = 1; submit_info.waitSemaphoreCount = 1;
submit_info.pWaitSemaphores = &image_available_signal_; submit_info.pWaitSemaphores = &frames_[current_frame_].image_available_signal;
submit_info.pWaitDstStageMask = &wait_stage; submit_info.pWaitDstStageMask = &wait_stage;
submit_info.commandBufferCount = 1; submit_info.commandBufferCount = 1;
submit_info.pCommandBuffers = &command_buffer_; submit_info.pCommandBuffers = &frames_[current_frame_].command_buffer;
submit_info.signalSemaphoreCount = 1; submit_info.signalSemaphoreCount = 1;
submit_info.pSignalSemaphores = &render_finished_signal_; submit_info.pSignalSemaphores =
&frames_[current_frame_].render_finished_signal;
VkResult submit_result = VkResult submit_result =
vkQueueSubmit(graphics_queue_, 1, &submit_info, still_rendering_fence_); vkQueueSubmit(graphics_queue_, 1, &submit_info,
frames_[current_frame_].still_rendering_fence);
if (submit_result != VK_SUCCESS) if (submit_result != VK_SUCCESS)
throw std::runtime_error("failed to submit draw commands!"); throw std::runtime_error("failed to submit draw commands!");
VkPresentInfoKHR present_info = {}; VkPresentInfoKHR present_info = {};
present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
present_info.waitSemaphoreCount = 1; present_info.waitSemaphoreCount = 1;
present_info.pWaitSemaphores = &render_finished_signal_; present_info.pWaitSemaphores =
&frames_[current_frame_].render_finished_signal;
present_info.swapchainCount = 1; present_info.swapchainCount = 1;
present_info.pSwapchains = &swap_chain_; present_info.pSwapchains = &swap_chain_;
present_info.pImageIndices = &current_image_index_; present_info.pImageIndices = &current_image_index_;
@@ -164,6 +184,8 @@ void veng::Graphics::EndFrame() {
RecreateSwapChain(); RecreateSwapChain();
else if (result != VK_SUCCESS) else if (result != VK_SUCCESS)
throw std::runtime_error("Failed to present swap chain image!"); throw std::runtime_error("Failed to present swap chain image!");
current_frame_ = (current_frame_++) % MAX_BUFFERED_FRAMES;
} }
} // namespace veng } // namespace veng

View File

@@ -149,6 +149,17 @@ void Graphics::CreateGraphicsPipeline() {
color_blending_info.attachmentCount = 1; color_blending_info.attachmentCount = 1;
color_blending_info.pAttachments = &color_blend_attachment; color_blending_info.pAttachments = &color_blend_attachment;
VkPipelineDepthStencilStateCreateInfo depth_stencil_info = {};
depth_stencil_info.sType =
VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
depth_stencil_info.depthTestEnable = VK_TRUE;
depth_stencil_info.depthWriteEnable = VK_TRUE;
depth_stencil_info.depthCompareOp = VK_COMPARE_OP_LESS;
depth_stencil_info.depthBoundsTestEnable = VK_TRUE;
depth_stencil_info.minDepthBounds = 0.f;
depth_stencil_info.maxDepthBounds = 1.f;
depth_stencil_info.stencilTestEnable = VK_FALSE;
VkPushConstantRange model_matrix_range = {}; VkPushConstantRange model_matrix_range = {};
model_matrix_range.offset = 0; model_matrix_range.offset = 0;
model_matrix_range.size = sizeof(glm::mat4); model_matrix_range.size = sizeof(glm::mat4);
@@ -177,7 +188,7 @@ void Graphics::CreateGraphicsPipeline() {
pipeline_info.pViewportState = &viewport_info; pipeline_info.pViewportState = &viewport_info;
pipeline_info.pRasterizationState = &rasterization_state_info; pipeline_info.pRasterizationState = &rasterization_state_info;
pipeline_info.pMultisampleState = &multisampling_info; pipeline_info.pMultisampleState = &multisampling_info;
pipeline_info.pDepthStencilState = nullptr; pipeline_info.pDepthStencilState = &depth_stencil_info;
pipeline_info.pColorBlendState = &color_blending_info; pipeline_info.pColorBlendState = &color_blending_info;
pipeline_info.pDynamicState = &dynamic_state_info; pipeline_info.pDynamicState = &dynamic_state_info;
pipeline_info.layout = pipeline_layout_; pipeline_info.layout = pipeline_layout_;
@@ -204,17 +215,50 @@ void Graphics::CreateRenderPass() {
color_attachment_ref.attachment = 0; color_attachment_ref.attachment = 0;
color_attachment_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; color_attachment_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkAttachmentDescription depth_attachment = {};
depth_attachment.format = VK_FORMAT_D32_SFLOAT;
depth_attachment.samples = VK_SAMPLE_COUNT_1_BIT;
depth_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
depth_attachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
depth_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
depth_attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
depth_attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
depth_attachment.finalLayout =
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
VkAttachmentReference depth_attachment_ref = {};
depth_attachment_ref.attachment = 1;
depth_attachment_ref.layout =
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
VkSubpassDescription main_subpass = {}; VkSubpassDescription main_subpass = {};
main_subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; main_subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
main_subpass.colorAttachmentCount = 1; main_subpass.colorAttachmentCount = 1;
main_subpass.pColorAttachments = &color_attachment_ref; main_subpass.pColorAttachments = &color_attachment_ref;
main_subpass.pDepthStencilAttachment = &depth_attachment_ref;
VkSubpassDependency dependency = {};
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
dependency.dstSubpass = 0;
dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
dependency.srcAccessMask = 0;
dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT |
VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
std::array<VkAttachmentDescription, 2> attachments = {color_attachment,
depth_attachment};
VkRenderPassCreateInfo render_pass_info = {}; VkRenderPassCreateInfo render_pass_info = {};
render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
render_pass_info.attachmentCount = 1; render_pass_info.attachmentCount = attachments.size();
render_pass_info.pAttachments = &color_attachment; render_pass_info.pAttachments = attachments.data();
render_pass_info.subpassCount = 1; render_pass_info.subpassCount = 1;
render_pass_info.pSubpasses = &main_subpass; render_pass_info.pSubpasses = &main_subpass;
render_pass_info.dependencyCount = 1;
render_pass_info.pDependencies = &dependency;
VkResult result = vkCreateRenderPass(logical_device_, &render_pass_info, VkResult result = vkCreateRenderPass(logical_device_, &render_pass_info,
nullptr, &render_pass_); nullptr, &render_pass_);
@@ -234,6 +278,7 @@ void veng::Graphics::RecreateSwapChain() {
CreateSwapChain(); CreateSwapChain();
CreateImageViews(); CreateImageViews();
CreateDepthResources();
CreateFramebuffers(); CreateFramebuffers();
} }
@@ -248,6 +293,14 @@ void veng::Graphics::CleanupSwapChain() {
if (swap_chain_ != VK_NULL_HANDLE) if (swap_chain_ != VK_NULL_HANDLE)
vkDestroySwapchainKHR(logical_device_, swap_chain_, nullptr); vkDestroySwapchainKHR(logical_device_, swap_chain_, nullptr);
vkDeviceWaitIdle(logical_device_);
vkDestroyImageView(logical_device_, depth_texture_.image_view, nullptr);
depth_texture_.image_view = VK_NULL_HANDLE;
vkDestroyImage(logical_device_, depth_texture_.image, nullptr);
depth_texture_.image = VK_NULL_HANDLE;
vkFreeMemory(logical_device_, depth_texture_.memory, nullptr);
depth_texture_.memory = VK_NULL_HANDLE;
} }
} // namespace veng } // namespace veng

View File

@@ -140,7 +140,7 @@ void Graphics::CreateSwapChain() {
swap_chain_images_.data()); swap_chain_images_.data());
} }
VkImageView Graphics::CreateImageView(VkImage image, VkFormat format) { VkImageView Graphics::CreateImageView(VkImage image, VkFormat format, VkImageAspectFlags aspect_flag) {
VkImageViewCreateInfo info = {}; VkImageViewCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
info.image = image; info.image = image;
@@ -150,7 +150,7 @@ VkImageView Graphics::CreateImageView(VkImage image, VkFormat format) {
info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; info.subresourceRange.aspectMask = aspect_flag;
info.subresourceRange.baseMipLevel = 0; info.subresourceRange.baseMipLevel = 0;
info.subresourceRange.levelCount = 1; info.subresourceRange.levelCount = 1;
info.subresourceRange.baseArrayLayer = 0; info.subresourceRange.baseArrayLayer = 0;
@@ -167,7 +167,7 @@ void Graphics::CreateImageViews() {
auto image_view_it = swap_chain_image_views_.begin(); auto image_view_it = swap_chain_image_views_.begin();
for (VkImage image : swap_chain_images_) { for (VkImage image : swap_chain_images_) {
*image_view_it = CreateImageView(image, surface_format_.format); *image_view_it = CreateImageView(image, surface_format_.format, VK_IMAGE_ASPECT_COLOR_BIT);
std::advance(image_view_it, 1); std::advance(image_view_it, 1);
} }

View File

@@ -52,7 +52,7 @@ TextureHandle Graphics::CreateTexture(gsl::czstring path) {
stbi_image_free(pixel_data); stbi_image_free(pixel_data);
TextureHandle handle = TextureHandle handle =
CreateImage(image_extents, CreateImage(image_extents, VK_FORMAT_R8G8B8A8_SRGB,
VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
@@ -62,7 +62,8 @@ TextureHandle Graphics::CreateTexture(gsl::czstring path) {
TransitionImageLayout(handle.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, TransitionImageLayout(handle.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
handle.image_view = CreateImageView(handle.image, VK_FORMAT_R8G8B8A8_SRGB); handle.image_view = CreateImageView(handle.image, VK_FORMAT_R8G8B8A8_SRGB,
VK_IMAGE_ASPECT_COLOR_BIT);
VkDescriptorSetAllocateInfo set_info = {}; VkDescriptorSetAllocateInfo set_info = {};
set_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; set_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
@@ -96,14 +97,23 @@ TextureHandle Graphics::CreateTexture(gsl::czstring path) {
void Graphics::DestroyTexture(TextureHandle handle) { void Graphics::DestroyTexture(TextureHandle handle) {
vkDeviceWaitIdle(logical_device_); vkDeviceWaitIdle(logical_device_);
vkFreeDescriptorSets(logical_device_, texture_pool_, 1, &handle.set);
vkDestroyImageView(logical_device_, handle.image_view, nullptr); if (handle.set != VK_NULL_HANDLE)
vkDestroyImage(logical_device_, handle.image, nullptr); vkFreeDescriptorSets(logical_device_, texture_pool_, 1, &handle.set);
vkFreeMemory(logical_device_, handle.memory, nullptr);
if (handle.image_view != VK_NULL_HANDLE)
vkDestroyImageView(logical_device_, handle.image_view, nullptr);
if (handle.image != VK_NULL_HANDLE)
vkDestroyImage(logical_device_, handle.image, nullptr);
if (handle.memory != VK_NULL_HANDLE)
vkFreeMemory(logical_device_, handle.memory, nullptr);
} }
void Graphics::SetTexture(TextureHandle handle) { void Graphics::SetTexture(TextureHandle handle) {
vkCmdBindDescriptorSets(command_buffer_, VK_PIPELINE_BIND_POINT_GRAPHICS, vkCmdBindDescriptorSets(frames_[current_frame_].command_buffer,
VK_PIPELINE_BIND_POINT_GRAPHICS,
pipeline_layout_, 1, 1, &handle.set, 0, nullptr); pipeline_layout_, 1, 1, &handle.set, 0, nullptr);
} }
@@ -118,7 +128,6 @@ void Graphics::TransitionImageLayout(VkImage image, VkImageLayout old_layout,
barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
barrier.image = image; barrier.image = image;
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
barrier.subresourceRange.baseArrayLayer = 0; barrier.subresourceRange.baseArrayLayer = 0;
barrier.subresourceRange.baseMipLevel = 0; barrier.subresourceRange.baseMipLevel = 0;
barrier.subresourceRange.levelCount = 1; barrier.subresourceRange.levelCount = 1;
@@ -139,8 +148,20 @@ void Graphics::TransitionImageLayout(VkImage image, VkImageLayout old_layout,
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
source_stage = VK_PIPELINE_STAGE_TRANSFER_BIT; source_stage = VK_PIPELINE_STAGE_TRANSFER_BIT;
destination_stage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; destination_stage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
} else if (old_layout == VK_IMAGE_LAYOUT_UNDEFINED &&
new_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
barrier.srcAccessMask = 0;
barrier.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
source_stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
destination_stage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
} }
if (new_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
else
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
vkCmdPipelineBarrier(local_command_buffer, source_stage, destination_stage, 0, vkCmdPipelineBarrier(local_command_buffer, source_stage, destination_stage, 0,
0, nullptr, 0, nullptr, 1, &barrier); 0, nullptr, 0, nullptr, 1, &barrier);
@@ -169,7 +190,8 @@ void Graphics::CopyBufferToImage(VkBuffer buffer, VkImage image,
EndTransientCommandBuffer(local_command_buffer); EndTransientCommandBuffer(local_command_buffer);
} }
TextureHandle Graphics::CreateImage(glm::ivec2 size, VkBufferUsageFlags usage, TextureHandle Graphics::CreateImage(glm::ivec2 size, VkFormat image_format,
VkBufferUsageFlags usage,
VkMemoryPropertyFlags properties) { VkMemoryPropertyFlags properties) {
TextureHandle handle = {}; TextureHandle handle = {};
@@ -183,7 +205,7 @@ TextureHandle Graphics::CreateImage(glm::ivec2 size, VkBufferUsageFlags usage,
image_info.extent.depth = 1; image_info.extent.depth = 1;
image_info.mipLevels = 1; image_info.mipLevels = 1;
image_info.arrayLayers = 1; image_info.arrayLayers = 1;
image_info.format = VK_FORMAT_R8G8B8A8_SRGB; image_info.format = image_format;
image_info.tiling = VK_IMAGE_TILING_OPTIMAL; image_info.tiling = VK_IMAGE_TILING_OPTIMAL;
image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
image_info.samples = VK_SAMPLE_COUNT_1_BIT; image_info.samples = VK_SAMPLE_COUNT_1_BIT;
@@ -216,4 +238,13 @@ TextureHandle Graphics::CreateImage(glm::ivec2 size, VkBufferUsageFlags usage,
return handle; return handle;
} }
void Graphics::CreateDepthResources() {
VkFormat kDepthFormat = VK_FORMAT_D32_SFLOAT;
depth_texture_ = CreateImage({extent_.width, extent_.height}, kDepthFormat,
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
depth_texture_.image_view = CreateImageView(
depth_texture_.image, kDepthFormat, VK_IMAGE_ASPECT_DEPTH_BIT);
}
} // namespace veng } // namespace veng