Added VkImage to image_t. For testing purposes draw all images in a sequence on screen aligned quad.
This commit is contained in:
parent
0b2685bb4b
commit
ab66921e14
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -5,5 +5,5 @@ bin/
|
||||||
*.suo
|
*.suo
|
||||||
*.user
|
*.user
|
||||||
config/visual-studio/.vs/
|
config/visual-studio/.vs/
|
||||||
|
config/visual-studio/vk_layer_settings.txt
|
||||||
|
config/visual-studio/vk_report
|
||||||
|
|
|
||||||
1847
data/model.obj
1847
data/model.obj
File diff suppressed because it is too large
Load Diff
BIN
data/texture.jpg
BIN
data/texture.jpg
Binary file not shown.
|
Before Width: | Height: | Size: 549 KiB |
|
|
@ -22,6 +22,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
// tr_image.c
|
// tr_image.c
|
||||||
#include "tr_local.h"
|
#include "tr_local.h"
|
||||||
|
|
||||||
|
// VULKAN
|
||||||
|
#include "vk_demo.h"
|
||||||
|
|
||||||
static void* q3_stbi_malloc(size_t size) {
|
static void* q3_stbi_malloc(size_t size) {
|
||||||
return ri.Malloc((int)size);
|
return ri.Malloc((int)size);
|
||||||
}
|
}
|
||||||
|
|
@ -787,6 +790,9 @@ image_t *R_CreateImage( const char *name, const byte *pic, int width, int height
|
||||||
image->next = hashTable[hash];
|
image->next = hashTable[hash];
|
||||||
hashTable[hash] = image;
|
hashTable[hash] = image;
|
||||||
|
|
||||||
|
// VULKAN
|
||||||
|
image->vk_image = vulkan_demo->create_texture(pic, 4, width, height, image->vk_image_view);
|
||||||
|
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
#include "tr_public.h"
|
#include "tr_public.h"
|
||||||
#include "qgl.h"
|
#include "qgl.h"
|
||||||
|
|
||||||
|
// VULKAN
|
||||||
|
#include "vk_definitions.h"
|
||||||
|
|
||||||
#define GL_INDEX_TYPE GL_UNSIGNED_INT
|
#define GL_INDEX_TYPE GL_UNSIGNED_INT
|
||||||
typedef unsigned int glIndex_t;
|
typedef unsigned int glIndex_t;
|
||||||
|
|
||||||
|
|
@ -104,6 +107,10 @@ typedef struct image_s {
|
||||||
qboolean allowPicmip;
|
qboolean allowPicmip;
|
||||||
int wrapClampMode; // GL_CLAMP or GL_REPEAT
|
int wrapClampMode; // GL_CLAMP or GL_REPEAT
|
||||||
|
|
||||||
|
// VULKAN
|
||||||
|
VkImage vk_image = VK_NULL_HANDLE;
|
||||||
|
VkImageView vk_image_view = VK_NULL_HANDLE;
|
||||||
|
|
||||||
struct image_s* next;
|
struct image_s* next;
|
||||||
} image_t;
|
} image_t;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,6 @@
|
||||||
|
|
||||||
#include "stb_image.h"
|
#include "stb_image.h"
|
||||||
|
|
||||||
#define TINYOBJLOADER_IMPLEMENTATION
|
|
||||||
#include "tiny_obj_loader.h"
|
|
||||||
|
|
||||||
#include "glm/glm.hpp"
|
#include "glm/glm.hpp"
|
||||||
#include "glm/gtc/matrix_transform.hpp"
|
#include "glm/gtc/matrix_transform.hpp"
|
||||||
#include "glm/gtx/hash.hpp"
|
#include "glm/gtx/hash.hpp"
|
||||||
|
|
@ -19,8 +16,7 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
const std::string model_path = "../../data/model.obj";
|
#include "tr_local.h"
|
||||||
const std::string texture_path = "../../data/texture.jpg";
|
|
||||||
|
|
||||||
struct Uniform_Buffer_Object {
|
struct Uniform_Buffer_Object {
|
||||||
glm::mat4 model;
|
glm::mat4 model;
|
||||||
|
|
@ -73,48 +69,16 @@ struct Model {
|
||||||
std::vector<uint32_t> indices;
|
std::vector<uint32_t> indices;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace std {
|
|
||||||
template<> struct hash<Vertex> {
|
|
||||||
size_t operator()(Vertex const& vertex) const {
|
|
||||||
return ((hash<glm::vec3>()(vertex.pos) ^
|
|
||||||
(hash<glm::vec3>()(vertex.color) << 1)) >> 1) ^
|
|
||||||
(hash<glm::vec2>()(vertex.tex_coord) << 1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static Model load_model() {
|
static Model load_model() {
|
||||||
tinyobj::attrib_t attrib;
|
float s = 1;
|
||||||
std::vector<tinyobj::shape_t> shapes;
|
|
||||||
std::vector<tinyobj::material_t> materials;
|
|
||||||
std::string err;
|
|
||||||
|
|
||||||
if (!tinyobj::LoadObj(&attrib, &shapes, &materials, &err, model_path.c_str()))
|
|
||||||
error("failed to load obj model: " + model_path);
|
|
||||||
|
|
||||||
Model model;
|
Model model;
|
||||||
std::unordered_map<Vertex, std::size_t> unique_vertices;
|
model.vertices = {
|
||||||
for (const auto& shape : shapes) {
|
{ {-s, -s, 0}, {1, 1, 1}, {0, 1} },
|
||||||
for (const auto& index : shape.mesh.indices) {
|
{ { s, -s, 0}, {1, 1, 1}, {1, 1} },
|
||||||
Vertex vertex;
|
{ { s, s, 0}, {1, 1, 1}, {1, 0} },
|
||||||
vertex.pos = {
|
{ {-s, s, 0}, {1, 1, 1}, {0, 0} },
|
||||||
attrib.vertices[3 * index.vertex_index + 0],
|
};
|
||||||
attrib.vertices[3 * index.vertex_index + 1],
|
model.indices = { 0, 1, 2, 0, 2, 3 };
|
||||||
attrib.vertices[3 * index.vertex_index + 2]
|
|
||||||
};
|
|
||||||
vertex.tex_coord = {
|
|
||||||
attrib.texcoords[2 * index.texcoord_index + 0],
|
|
||||||
1.0 - attrib.texcoords[2 * index.texcoord_index + 1]
|
|
||||||
};
|
|
||||||
vertex.color = {1.0f, 1.0f, 1.0f};
|
|
||||||
|
|
||||||
if (unique_vertices.count(vertex) == 0) {
|
|
||||||
unique_vertices[vertex] = model.vertices.size();
|
|
||||||
model.vertices.push_back(vertex);
|
|
||||||
}
|
|
||||||
model.indices.push_back((uint32_t)unique_vertices[vertex]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -144,15 +108,22 @@ Vulkan_Demo::Vulkan_Demo(int window_width, int window_height, const SDL_SysWMinf
|
||||||
initialize_vulkan(window_sys_info);
|
initialize_vulkan(window_sys_info);
|
||||||
get_allocator()->initialize(get_physical_device(), get_device());
|
get_allocator()->initialize(get_physical_device(), get_device());
|
||||||
get_resource_manager()->initialize(get_device());
|
get_resource_manager()->initialize(get_device());
|
||||||
|
create_command_pool();
|
||||||
|
|
||||||
image_acquired = get_resource_manager()->create_semaphore();
|
image_acquired = get_resource_manager()->create_semaphore();
|
||||||
rendering_finished = get_resource_manager()->create_semaphore();
|
rendering_finished = get_resource_manager()->create_semaphore();
|
||||||
|
|
||||||
create_command_pool();
|
VkFenceCreateInfo fence_desc;
|
||||||
|
fence_desc.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||||
|
fence_desc.pNext = nullptr;
|
||||||
|
fence_desc.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
||||||
|
VkResult result = vkCreateFence(get_device(), &fence_desc, nullptr, &rendering_finished_fence);
|
||||||
|
check_vk_result(result, "vkCreateFence");
|
||||||
|
|
||||||
create_descriptor_pool();
|
create_descriptor_pool();
|
||||||
|
|
||||||
create_uniform_buffer();
|
create_uniform_buffer();
|
||||||
create_texture();
|
|
||||||
create_texture_sampler();
|
create_texture_sampler();
|
||||||
create_depth_buffer_resources();
|
create_depth_buffer_resources();
|
||||||
|
|
||||||
|
|
@ -164,8 +135,29 @@ Vulkan_Demo::Vulkan_Demo(int window_width, int window_height, const SDL_SysWMinf
|
||||||
create_pipeline();
|
create_pipeline();
|
||||||
|
|
||||||
upload_geometry();
|
upload_geometry();
|
||||||
record_render_scene(); // record secondary command buffer before primary ones
|
|
||||||
record_render_frame();
|
{
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
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_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());
|
||||||
|
check_vk_result(result, "vkAllocateCommandBuffers");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Vulkan_Demo::~Vulkan_Demo() {
|
Vulkan_Demo::~Vulkan_Demo() {
|
||||||
|
|
@ -183,7 +175,7 @@ void Vulkan_Demo::create_command_pool() {
|
||||||
VkCommandPoolCreateInfo desc;
|
VkCommandPoolCreateInfo desc;
|
||||||
desc.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
desc.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||||
desc.pNext = nullptr;
|
desc.pNext = nullptr;
|
||||||
desc.flags = 0;
|
desc.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
||||||
desc.queueFamilyIndex = get_queue_family_index();
|
desc.queueFamilyIndex = get_queue_family_index();
|
||||||
command_pool = get_resource_manager()->create_command_pool(desc);
|
command_pool = get_resource_manager()->create_command_pool(desc);
|
||||||
}
|
}
|
||||||
|
|
@ -212,22 +204,19 @@ void Vulkan_Demo::create_uniform_buffer() {
|
||||||
uniform_buffer = create_buffer(size, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
|
uniform_buffer = create_buffer(size, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vulkan_Demo::create_texture() {
|
VkImage Vulkan_Demo::create_texture(const uint8_t* pixels, int bytes_per_pixel, int image_width, int image_height, VkImageView& image_view) {
|
||||||
int image_width, image_height, image_component_count;
|
VkImage staging_image = create_staging_texture(image_width, image_height,
|
||||||
auto rgba_pixels = stbi_load(texture_path.c_str(), &image_width, &image_height, &image_component_count, STBI_rgb_alpha);
|
bytes_per_pixel == 3 ? VK_FORMAT_R8G8B8_UNORM : VK_FORMAT_R8G8B8A8_UNORM, pixels, bytes_per_pixel);
|
||||||
if (rgba_pixels == nullptr) {
|
|
||||||
error("failed to load image file");
|
|
||||||
}
|
|
||||||
VkImage staging_image = create_staging_texture(image_width, image_height, VK_FORMAT_R8G8B8A8_UNORM, rgba_pixels, 4);
|
|
||||||
Defer_Action destroy_staging_image([this, &staging_image]() {
|
Defer_Action destroy_staging_image([this, &staging_image]() {
|
||||||
vkDestroyImage(get_device(), staging_image, nullptr);
|
vkDestroyImage(get_device(), staging_image, nullptr);
|
||||||
});
|
});
|
||||||
stbi_image_free(rgba_pixels);
|
|
||||||
|
VkImage texture_image = ::create_texture(image_width, image_height,
|
||||||
texture_image = ::create_texture(image_width, image_height, VK_FORMAT_R8G8B8A8_UNORM);
|
bytes_per_pixel == 3 ? VK_FORMAT_R8G8B8_UNORM : VK_FORMAT_R8G8B8A8_UNORM);
|
||||||
|
|
||||||
record_and_run_commands(command_pool, get_queue(),
|
record_and_run_commands(command_pool, get_queue(),
|
||||||
[&staging_image, &image_width, &image_height, this](VkCommandBuffer command_buffer) {
|
[&texture_image, &staging_image, &image_width, &image_height, this](VkCommandBuffer command_buffer) {
|
||||||
|
|
||||||
record_image_layout_transition(command_buffer, staging_image, VK_FORMAT_R8G8B8A8_UNORM,
|
record_image_layout_transition(command_buffer, staging_image, VK_FORMAT_R8G8B8A8_UNORM,
|
||||||
VK_ACCESS_HOST_WRITE_BIT, VK_IMAGE_LAYOUT_PREINITIALIZED, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
VK_ACCESS_HOST_WRITE_BIT, VK_IMAGE_LAYOUT_PREINITIALIZED, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||||
|
|
@ -259,7 +248,8 @@ void Vulkan_Demo::create_texture() {
|
||||||
VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_SHADER_READ_BIT, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||||
});
|
});
|
||||||
|
|
||||||
texture_image_view = create_image_view(texture_image, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_ASPECT_COLOR_BIT);
|
image_view = create_image_view(texture_image, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||||
|
return texture_image;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vulkan_Demo::create_texture_sampler() {
|
void Vulkan_Demo::create_texture_sampler() {
|
||||||
|
|
@ -331,41 +321,6 @@ void Vulkan_Demo::create_descriptor_set() {
|
||||||
|
|
||||||
VkResult result = vkAllocateDescriptorSets(get_device(), &desc, &descriptor_set);
|
VkResult result = vkAllocateDescriptorSets(get_device(), &desc, &descriptor_set);
|
||||||
check_vk_result(result, "vkAllocateDescriptorSets");
|
check_vk_result(result, "vkAllocateDescriptorSets");
|
||||||
|
|
||||||
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 = texture_image_view;
|
|
||||||
image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
|
||||||
|
|
||||||
std::array<VkWriteDescriptorSet, 2> descriptor_writes;
|
|
||||||
descriptor_writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
|
||||||
descriptor_writes[0].pNext = nullptr;
|
|
||||||
descriptor_writes[0].dstSet = descriptor_set;
|
|
||||||
descriptor_writes[0].dstBinding = 0;
|
|
||||||
descriptor_writes[0].dstArrayElement = 0;
|
|
||||||
descriptor_writes[0].descriptorCount = 1;
|
|
||||||
descriptor_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
|
||||||
descriptor_writes[0].pImageInfo = nullptr;
|
|
||||||
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::create_render_pass() {
|
void Vulkan_Demo::create_render_pass() {
|
||||||
|
|
@ -646,15 +601,6 @@ void Vulkan_Demo::upload_geometry() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vulkan_Demo::record_render_scene() {
|
void Vulkan_Demo::record_render_scene() {
|
||||||
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;
|
|
||||||
VkResult result = vkAllocateCommandBuffers(get_device(), &alloc_info, &render_scene_command_buffer);
|
|
||||||
check_vk_result(result, "vkAllocateCommandBuffers");
|
|
||||||
|
|
||||||
VkCommandBufferInheritanceInfo inheritance_info;
|
VkCommandBufferInheritanceInfo inheritance_info;
|
||||||
inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
|
inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
|
||||||
inheritance_info.pNext = nullptr;
|
inheritance_info.pNext = nullptr;
|
||||||
|
|
@ -668,10 +614,10 @@ void Vulkan_Demo::record_render_scene() {
|
||||||
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;
|
||||||
begin_info.pNext = nullptr;
|
begin_info.pNext = nullptr;
|
||||||
begin_info.flags = VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT | VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
|
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;
|
begin_info.pInheritanceInfo = &inheritance_info;
|
||||||
|
|
||||||
result = vkBeginCommandBuffer(render_scene_command_buffer, &begin_info);
|
VkResult result = vkBeginCommandBuffer(render_scene_command_buffer, &begin_info);
|
||||||
check_vk_result(result, "vkBeginCommandBuffer");
|
check_vk_result(result, "vkBeginCommandBuffer");
|
||||||
|
|
||||||
const VkDeviceSize offset = 0;
|
const VkDeviceSize offset = 0;
|
||||||
|
|
@ -686,20 +632,10 @@ void Vulkan_Demo::record_render_scene() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vulkan_Demo::record_render_frame() {
|
void Vulkan_Demo::record_render_frame() {
|
||||||
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_PRIMARY;
|
|
||||||
alloc_info.commandBufferCount = static_cast<uint32_t>(get_swapchain_image_views().size());
|
|
||||||
render_frame_command_buffers.resize(get_swapchain_image_views().size());
|
|
||||||
VkResult result = vkAllocateCommandBuffers(get_device(), &alloc_info, render_frame_command_buffers.data());
|
|
||||||
check_vk_result(result, "vkAllocateCommandBuffers");
|
|
||||||
|
|
||||||
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;
|
||||||
begin_info.pNext = nullptr;
|
begin_info.pNext = nullptr;
|
||||||
begin_info.flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT;
|
begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||||
begin_info.pInheritanceInfo = nullptr;
|
begin_info.pInheritanceInfo = nullptr;
|
||||||
|
|
||||||
std::array<VkClearValue, 2> clear_values;
|
std::array<VkClearValue, 2> clear_values;
|
||||||
|
|
@ -750,17 +686,64 @@ void Vulkan_Demo::record_render_frame() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
descriptor_writes[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
|
descriptor_writes[0].pNext = nullptr;
|
||||||
|
descriptor_writes[0].dstSet = descriptor_set;
|
||||||
|
descriptor_writes[0].dstBinding = 0;
|
||||||
|
descriptor_writes[0].dstArrayElement = 0;
|
||||||
|
descriptor_writes[0].descriptorCount = 1;
|
||||||
|
descriptor_writes[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||||
|
descriptor_writes[0].pImageInfo = nullptr;
|
||||||
|
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_uniform_buffer() {
|
void Vulkan_Demo::update_uniform_buffer() {
|
||||||
static auto start_time = std::chrono::high_resolution_clock::now();
|
static auto start_time = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
auto current_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;
|
float time = std::chrono::duration_cast<std::chrono::milliseconds>(current_time - start_time).count() / 1000.f;
|
||||||
|
time = 0.0;
|
||||||
|
|
||||||
Uniform_Buffer_Object ubo;
|
Uniform_Buffer_Object ubo;
|
||||||
ubo.model = glm::rotate(glm::mat4(), time * glm::radians(30.0f), glm::vec3(0, 1, 0)) *
|
ubo.model = glm::rotate(glm::mat4(), time * glm::radians(30.0f), glm::vec3(0, 1, 0));
|
||||||
glm::scale(glm::mat4(), glm::vec3(0.015f));
|
|
||||||
|
|
||||||
ubo.view = glm::lookAt(glm::vec3(0.5, 1.4, 2.8), glm::vec3(0, 0.7, 0), glm::vec3(0, 1, 0));
|
ubo.view = glm::lookAt(glm::vec3(0.0, 0.0, 2.8), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
|
||||||
|
|
||||||
// Vulkan clip space has inverted Y and half Z.
|
// Vulkan clip space has inverted Y and half Z.
|
||||||
const glm::mat4 clip(
|
const glm::mat4 clip(
|
||||||
|
|
@ -779,10 +762,18 @@ void Vulkan_Demo::update_uniform_buffer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Vulkan_Demo::run_frame() {
|
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
|
||||||
|
record_render_frame();
|
||||||
|
|
||||||
update_uniform_buffer();
|
update_uniform_buffer();
|
||||||
|
|
||||||
uint32_t swapchain_image_index;
|
uint32_t swapchain_image_index;
|
||||||
VkResult result = vkAcquireNextImageKHR(get_device(), get_swapchain(), UINT64_MAX, image_acquired, VK_NULL_HANDLE, &swapchain_image_index);
|
result = vkAcquireNextImageKHR(get_device(), get_swapchain(), UINT64_MAX, image_acquired, VK_NULL_HANDLE, &swapchain_image_index);
|
||||||
check_vk_result(result, "vkAcquireNextImageKHR");
|
check_vk_result(result, "vkAcquireNextImageKHR");
|
||||||
|
|
||||||
VkPipelineStageFlags wait_dst_stage_mask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
VkPipelineStageFlags wait_dst_stage_mask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
||||||
|
|
@ -798,9 +789,9 @@ void Vulkan_Demo::run_frame() {
|
||||||
submit_info.signalSemaphoreCount = 1;
|
submit_info.signalSemaphoreCount = 1;
|
||||||
submit_info.pSignalSemaphores = &rendering_finished;
|
submit_info.pSignalSemaphores = &rendering_finished;
|
||||||
|
|
||||||
result = vkQueueSubmit(get_queue(), 1, &submit_info, VK_NULL_HANDLE);
|
result = vkQueueSubmit(get_queue(), 1, &submit_info, rendering_finished_fence);
|
||||||
check_vk_result(result, "vkQueueSubmit");
|
check_vk_result(result, "vkQueueSubmit");
|
||||||
|
|
||||||
VkSwapchainKHR swapchain = get_swapchain();
|
VkSwapchainKHR swapchain = get_swapchain();
|
||||||
VkPresentInfoKHR present_info;
|
VkPresentInfoKHR present_info;
|
||||||
present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,12 @@ public:
|
||||||
|
|
||||||
void run_frame();
|
void run_frame();
|
||||||
|
|
||||||
private:
|
public:
|
||||||
void create_command_pool();
|
void create_command_pool();
|
||||||
void create_descriptor_pool();
|
void create_descriptor_pool();
|
||||||
|
|
||||||
void create_uniform_buffer();
|
void create_uniform_buffer();
|
||||||
void create_texture();
|
VkImage create_texture(const uint8_t* pixels, int bytes_per_pixel, int width, int height, VkImageView& image_view);
|
||||||
void create_texture_sampler();
|
void create_texture_sampler();
|
||||||
void create_depth_buffer_resources();
|
void create_depth_buffer_resources();
|
||||||
|
|
||||||
|
|
@ -32,6 +32,7 @@ private:
|
||||||
void upload_geometry();
|
void upload_geometry();
|
||||||
void record_render_scene();
|
void record_render_scene();
|
||||||
void record_render_frame();
|
void record_render_frame();
|
||||||
|
void update_descriptor_set();
|
||||||
void update_uniform_buffer();
|
void update_uniform_buffer();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -40,6 +41,7 @@ private:
|
||||||
|
|
||||||
VkSemaphore image_acquired = VK_NULL_HANDLE;
|
VkSemaphore image_acquired = VK_NULL_HANDLE;
|
||||||
VkSemaphore rendering_finished = VK_NULL_HANDLE;
|
VkSemaphore rendering_finished = VK_NULL_HANDLE;
|
||||||
|
VkFence rendering_finished_fence = VK_NULL_HANDLE;
|
||||||
|
|
||||||
VkCommandPool command_pool = VK_NULL_HANDLE;
|
VkCommandPool command_pool = VK_NULL_HANDLE;
|
||||||
VkDescriptorPool descriptor_pool = VK_NULL_HANDLE;
|
VkDescriptorPool descriptor_pool = VK_NULL_HANDLE;
|
||||||
|
|
@ -47,8 +49,7 @@ private:
|
||||||
VkBuffer uniform_staging_buffer = VK_NULL_HANDLE;
|
VkBuffer uniform_staging_buffer = VK_NULL_HANDLE;
|
||||||
VkDeviceMemory uniform_staging_buffer_memory = VK_NULL_HANDLE;
|
VkDeviceMemory uniform_staging_buffer_memory = VK_NULL_HANDLE;
|
||||||
VkBuffer uniform_buffer = VK_NULL_HANDLE;
|
VkBuffer uniform_buffer = VK_NULL_HANDLE;
|
||||||
VkImage texture_image = VK_NULL_HANDLE;
|
|
||||||
VkImageView texture_image_view = VK_NULL_HANDLE;
|
|
||||||
VkSampler texture_image_sampler = VK_NULL_HANDLE;
|
VkSampler texture_image_sampler = VK_NULL_HANDLE;
|
||||||
VkImage depth_image = VK_NULL_HANDLE;
|
VkImage depth_image = VK_NULL_HANDLE;
|
||||||
VkImageView depth_image_view = VK_NULL_HANDLE;
|
VkImageView depth_image_view = VK_NULL_HANDLE;
|
||||||
|
|
|
||||||
2020
third_party/include/tiny_obj_loader.h
vendored
2020
third_party/include/tiny_obj_loader.h
vendored
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user