aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorladevieq <ladevie.quentin@gmail.com>2022-09-08 23:04:06 +0200
committerladevieq <ladevie.quentin@gmail.com>2022-09-08 23:04:06 +0200
commit2d16fbd7e235bf2cc96d451469d8d39cae1917c3 (patch)
treeab565ca756c6341ec36f91835d548cfd989b6e1f /src
parentb7c2511e588f1da63413a38a624fd3e6bb8cf54d (diff)
First render using new texture uploading system
Diffstat (limited to 'src')
-rw-r--r--src/compute-renderpass.cpp4
-rw-r--r--src/gltf.cpp26
-rw-r--r--src/main.cpp8
-rw-r--r--src/mesh.cpp2
-rw-r--r--src/primitive-renderpass.cpp8
-rw-r--r--src/scene.cpp35
-rw-r--r--src/vk-api.cpp7
-rw-r--r--src/vk-context.cpp2
-rw-r--r--src/vk-renderer.cpp49
9 files changed, 82 insertions, 59 deletions
diff --git a/src/compute-renderpass.cpp b/src/compute-renderpass.cpp
index 9a1d43e..d5dbaa0 100644
--- a/src/compute-renderpass.cpp
+++ b/src/compute-renderpass.cpp
@@ -19,7 +19,7 @@ void ComputeRenderpass::set_pipeline(const char* shader_name) {
void ComputeRenderpass::set_ouput_texture(Texture* out_texture) {
this->output_texture = out_texture;
- auto image = api.get_image(output_texture->device_image);
+ const auto& image = api.get_image(output_texture->device_image);
// TODO: Remove hardcoded offset
memcpy(constants + 56, &image.bindless_storage_index, sizeof(bindless_index));
@@ -36,7 +36,7 @@ void ComputeRenderpass::set_constant(off_t offset, uint64_t* constant) {
}
void ComputeRenderpass::set_constant(off_t offset, Texture* texture) {
- auto image = api.get_image(texture->device_image);
+ const auto& image = api.get_image(texture->device_image);
memcpy(constants + offset, (void*)&image.bindless_storage_index, sizeof(bindless_index));
diff --git a/src/gltf.cpp b/src/gltf.cpp
index 882a64b..64e5644 100644
--- a/src/gltf.cpp
+++ b/src/gltf.cpp
@@ -69,7 +69,7 @@ void gltf::load_meshes() {
const auto &primitives = gltf_meshes[mesh_index]["primitives"];
for (const auto &primitive : primitives) {
- auto material = materials[primitive["material"].get<uint32_t>()];
+ auto& material = materials[primitive["material"].get<uint32_t>()];
mesh.add_submesh(load_primitive(primitive), material);
}
@@ -121,13 +121,14 @@ void gltf::load_textures(const std::filesystem::path &path) {
image.data = stbi_load(filepath.c_str(), &image.x, &image.y, &image.n, 4);
}
- const auto &gltf_samplers = gltf_json["samplers"];
- auto samplers_count = gltf_samplers.size();
- std::vector<Sampler *> samplers{samplers_count};
+ // const auto &gltf_samplers = gltf_json["samplers"];
+ // auto samplers_count = gltf_samplers.size();
+ // std::vector<Sampler *> samplers{samplers_count};
- for (size_t sampler_index = 0; sampler_index < samplers_count; sampler_index++) {
- samplers[sampler_index] = vkrenderer::create_sampler(VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_REPEAT);
- }
+ Sampler* sampler = vkrenderer::create_sampler(VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_REPEAT);
+ // for (size_t sampler_index = 0; sampler_index < samplers_count; sampler_index++) {
+ // samplers[sampler_index] = vkrenderer::create_sampler(VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_REPEAT);
+ // }
const auto &gltf_textures = gltf_json["textures"];
auto textures_count = gltf_textures.size();
@@ -137,18 +138,15 @@ void gltf::load_textures(const std::filesystem::path &path) {
auto gltf_texture = gltf_textures[texture_index];
auto& image = images[gltf_texture["source"].get<uint32_t>()];
- Sampler *sampler = nullptr;
- if (gltf_texture.contains("sampler")) {
- auto sampler_index = gltf_texture["sampler"].get<uint32_t>();
- sampler = samplers[sampler_index];
- }
+ // if (gltf_texture.contains("sampler")) {
+ // auto sampler_index = gltf_texture["sampler"].get<uint32_t>();
+ // sampler = samplers[sampler_index];
+ // }
auto *texture = vkrenderer::create_2d_texture(static_cast<uint32_t>(image.x), static_cast<uint32_t>(image.y), VK_FORMAT_R8G8B8A8_UNORM, sampler);
texture->update(image.data);
- stbi_image_free(image.data);
-
textures[texture_index] = texture;
}
}
diff --git a/src/main.cpp b/src/main.cpp
index 5e39a09..805a0b4 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -319,8 +319,8 @@ int main() {
renderer.recreate_swapchain();
main_scene.meta.cam.set_aspect_ratio((float)event.width / (float)event.height);
- vkrenderer::destroy_2d_texture(accumulation_texture);
- vkrenderer::destroy_2d_texture(output_texture);
+ delete accumulation_texture;
+ delete output_texture;
accumulation_texture = vkrenderer::create_2d_texture(event.width, event.height, VK_FORMAT_R32G32B32A32_SFLOAT);
output_texture = vkrenderer::create_2d_texture(event.width, event.height, VK_FORMAT_R32G32B32A32_SFLOAT);
raytracing_pass->set_dispatch_size(event.width / 8 + 1, event.height / 8 + 1, 1);
@@ -406,6 +406,8 @@ int main() {
raytracing_pass->set_ouput_texture(output_texture);
raytracing_pass->set_constant(60, accumulation_texture);
+ renderer.begin_frame();
+
// update_ui(main_scene, delta_time);
if (can_render) {
@@ -414,6 +416,8 @@ int main() {
std::swap(output_texture, accumulation_texture);
}
+ renderer.finish_frame();
+
frame_count++;
}
diff --git a/src/mesh.cpp b/src/mesh.cpp
index b3916aa..3863ca8 100644
--- a/src/mesh.cpp
+++ b/src/mesh.cpp
@@ -42,5 +42,5 @@ void Mesh::add_submesh(const submesh& submesh, material& material) {
}
void Mesh::register_mesh(const Mesh& mesh) {
- meshes.emplace_back(mesh);
+ meshes.push_back(mesh);
}
diff --git a/src/primitive-renderpass.cpp b/src/primitive-renderpass.cpp
index 316cf6d..45d48e8 100644
--- a/src/primitive-renderpass.cpp
+++ b/src/primitive-renderpass.cpp
@@ -25,18 +25,18 @@ void Primitive::set_constant(off_t offset, uint64_t* constant) {
}
void Primitive::set_constant(off_t offset, Texture* texture) {
- auto image = api.get_image(texture->device_image);
+ const auto& image = api.get_image(texture->device_image);
memcpy(constants + offset, (void*)&image.bindless_storage_index, sizeof(bindless_index));
}
void Primitive::set_constant(off_t offset, Buffer* buffer) {
- auto device_buffer = api.get_buffer(buffer->device_buffer);
+ const auto& device_buffer = api.get_buffer(buffer->device_buffer);
memcpy(constants + offset, (void*)&device_buffer.device_address, sizeof(VkDeviceAddress));
}
void Primitive::set_constant(off_t offset, Sampler* sampler) {
- auto device_sampler = api.get_sampler(sampler->device_sampler);
+ const auto& device_sampler = api.get_sampler(sampler->device_sampler);
memcpy(constants + offset, (void*)&device_sampler.bindless_index, sizeof(bindless_index));
}
@@ -93,7 +93,7 @@ void PrimitiveRenderpass::set_viewport(float x, float y, float width, float heig
}
void PrimitiveRenderpass::set_color_attachment(uint32_t index, Texture* attachment) {
- auto device_image = api.get_image(attachment->device_image);
+ const auto& device_image = api.get_image(attachment->device_image);
if (device_image.size.width != framebuffers[0].size.width ||
device_image.size.height != framebuffers[0].size.height) {
diff --git a/src/scene.cpp b/src/scene.cpp
index f58ac30..dcbafe3 100644
--- a/src/scene.cpp
+++ b/src/scene.cpp
@@ -65,11 +65,11 @@ scene::scene(const camera& cam, uint32_t width, uint32_t height)
:meta(cam, width, height){
// Geometry & BVH
- std::vector<uint32_t> indices;
- std::vector<float> positions;
- std::vector<float> normals;
- std::vector<float> uvs;
- std::vector<material> materials;
+ std::vector<uint32_t> indices;
+ std::vector<float> positions;
+ std::vector<float> normals;
+ std::vector<float> uvs;
+ std::vector<gpu_material> materials;
std::vector<packed_bvh_node> packed_nodes;
// auto root_node = gltf::load("../models/BistroInterior", "BistroInterior.gltf");
@@ -140,7 +140,26 @@ scene::scene(const camera& cam, uint32_t width, uint32_t height)
indices[triangle_offset + 1] = (submesh_level_index_2 + vertex_offset); // | (0xff000000 & (materials.size() << 16));
indices[triangle_offset + 2] = (submesh_level_index_3 + vertex_offset); // | (0xff000000 & (materials.size() << 24));
- // materials.push_back(submesh.mat);
+ const auto& material = submesh.material;
+ const auto& albedo_image = vkrenderer::api.get_image(material.base_color_texture->device_image);
+ const auto& albedo_sampler = vkrenderer::api.get_sampler(material.base_color_texture->sampler->device_sampler);
+
+ materials.emplace_back(gpu_material {
+ .base_color = material.base_color,
+ .albedo_texture_id = albedo_image.bindless_sampled_index,
+ .albedo_texture_sampler_id = albedo_sampler.bindless_index,
+ .metalness = material.metalness,
+ .roughness = material.roughness
+ });
+
+ if (material.metallic_roughness_texture != nullptr) {
+ auto& gpu_material = materials.back();
+ const auto& metallic_roughness_image = vkrenderer::api.get_image(material.metallic_roughness_texture->device_image);
+ const auto& metallic_roughness_sampler = vkrenderer::api.get_sampler(material.metallic_roughness_texture->sampler->device_sampler);
+
+ gpu_material.metallic_roughness_texture_id = metallic_roughness_image.bindless_sampled_index;
+ gpu_material.metallic_roughness_texture_sampler_id = metallic_roughness_sampler.bindless_index;
+ }
}
}
@@ -180,6 +199,6 @@ scene::scene(const camera& cam, uint32_t width, uint32_t height)
bvh_buffer = vkrenderer::create_buffer(packed_nodes.size() * sizeof(packed_nodes[0]));
bvh_buffer->write(packed_nodes.data(), 0, packed_nodes.size() * sizeof(packed_nodes[0]));
- // materials_buffer = vkrenderer::create_buffer(materials.size() * sizeof(materials[0]));
- // materials_buffer->write(materials.data(), 0, materials.size() * sizeof(materials[0]));
+ materials_buffer = vkrenderer::create_buffer(materials.size() * sizeof(materials[0]));
+ materials_buffer->write(materials.data(), 0, materials.size() * sizeof(materials[0]));
}
diff --git a/src/vk-api.cpp b/src/vk-api.cpp
index 04e5cc0..cb9ec0a 100644
--- a/src/vk-api.cpp
+++ b/src/vk-api.cpp
@@ -281,6 +281,7 @@ handle vkapi::create_image(VkExtent3D size, VkFormat format, VkImageUsageFlags u
VKRESULT(vkCreateImageView(context.device, &image_view_create_info, VK_NULL_HANDLE, &image->view))
+ image->format = format;
image->usages = usages;
image->device_ptr = alloc_info.pMappedData;
@@ -1226,7 +1227,7 @@ void vkapi::end_record(VkCommandBuffer command_buffer) {
VKRESULT(vkEndCommandBuffer(command_buffer))
}
-VkResult vkapi::submit_graphics(VkCommandBuffer command_buffer, VkSemaphore wait_semaphore, VkSemaphore signal_semaphore, VkFence submission_fence) const {
+VkResult vkapi::submit(VkCommandBuffer command_buffers[], size_t command_buffers_count, VkSemaphore wait_semaphore, VkSemaphore signal_semaphore, VkFence submission_fence) const {
VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
VkSubmitInfo submit_info = {};
@@ -1237,8 +1238,8 @@ VkResult vkapi::submit_graphics(VkCommandBuffer command_buffer, VkSemaphore wait
submit_info.pWaitDstStageMask = wait_semaphore != nullptr ? &wait_stage : VK_NULL_HANDLE;
submit_info.signalSemaphoreCount = signal_semaphore != nullptr ? 1 : 0;
submit_info.pSignalSemaphores = &signal_semaphore;
- submit_info.commandBufferCount = 1;
- submit_info.pCommandBuffers = &command_buffer;
+ submit_info.commandBufferCount = command_buffers_count;
+ submit_info.pCommandBuffers = command_buffers;
return vkQueueSubmit(context.graphics_queue.handle, 1, &submit_info, submission_fence);
}
diff --git a/src/vk-context.cpp b/src/vk-context.cpp
index e4a8815..824c216 100644
--- a/src/vk-context.cpp
+++ b/src/vk-context.cpp
@@ -284,7 +284,7 @@ void vkcontext::check_available_instance_extensions(const char* needed_extension
}
}
- assert(available_needed_extensions_count == needed_extensions_count);
+ // assert(available_needed_extensions_count == needed_extensions_count);
}
bool vkcontext::support_required_features(VkPhysicalDevice physical_device) {
diff --git a/src/vk-renderer.cpp b/src/vk-renderer.cpp
index bfe8e5d..1cbf0be 100644
--- a/src/vk-renderer.cpp
+++ b/src/vk-renderer.cpp
@@ -52,6 +52,7 @@ vkrenderer::vkrenderer(window& wnd) {
api.allocate_command_buffers(copy_command_pools[index], &copy_command_buffers[index], 1);
// staging_buffers[index] = create_staging_buffer(4096 * 4096 * sizeof(uint32_t));
+ staging_buffers[index] = new RingBuffer(4096ULL * 4096ULL * sizeof(uint32_t));
}
}
@@ -64,15 +65,16 @@ vkrenderer::~vkrenderer() {
for(size_t index { 0 }; index < virtual_frames_count; index++) {
vkFreeCommandBuffers(context.device, copy_command_pools[index], 1, &copy_command_buffers[index]);
+ vkDestroyCommandPool(context.device, copy_command_pools[index], nullptr);
}
api.destroy_fences(submission_fences, virtual_frames_count);
api.destroy_semaphores(execution_semaphores, virtual_frames_count);
api.destroy_semaphores(acquire_semaphores, virtual_frames_count);
+ vkFreeCommandBuffers(context.device, graphics_command_pool, virtual_frames_count, graphics_command_buffers);
vkDestroyCommandPool(context.device, graphics_command_pool, nullptr);
- vkFreeCommandBuffers(context.device, graphics_command_pool, virtual_frames_count, graphics_command_buffers);
api.destroy_pipeline(tonemapping_pipeline);
@@ -109,7 +111,9 @@ void vkrenderer::update_images() {
VkCommandBuffer command_buffer = copy_command_buffers[virtual_frame_index];
vkrenderer::api.start_record(command_buffer);
- for (auto* texture : upload_queue) {
+ while(!upload_queue.empty()) {
+ auto* texture = upload_queue.back();
+ upload_queue.pop_back();
auto texture_size = texture->size();
auto offset = staging_buffer->alloc(texture_size);
@@ -119,10 +123,14 @@ void vkrenderer::update_images() {
staging_buffer->write(texture->data, offset, texture_size);
+ vkrenderer::api.image_barrier(command_buffer, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, texture->device_image);
vkrenderer::api.copy_buffer(command_buffer, staging_buffer->device_buffer, texture->device_image, offset);
+ vkrenderer::api.image_barrier(command_buffer, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, texture->device_image);
}
vkrenderer::api.end_record(command_buffer);
+
+ recorded_command_buffers.push_back(command_buffer);
}
Buffer* vkrenderer::create_buffer(size_t size) {
@@ -141,11 +149,6 @@ Texture* vkrenderer::create_2d_texture(size_t width, size_t height, VkFormat for
return new Texture(width, height, 1, format, sampler);
}
-void vkrenderer::destroy_2d_texture(Texture* texture) {
- api.destroy_image(texture->device_image);
- delete texture;
-}
-
// TODO: Check if a similar sampler has been allocated
Sampler* vkrenderer::create_sampler(VkFilter filter, VkSamplerAddressMode address_mode) {
auto* sampler = new Sampler();
@@ -172,10 +175,16 @@ Primitive* vkrenderer::create_primitive(PrimitiveRenderpass& primitive_render_pa
}
void vkrenderer::render() {
- begin_frame();
+ swapchain_image_index = 0;
+ auto acquire_result = vkAcquireNextImageKHR(context.device, swapchain.handle, UINT64_MAX, acquire_semaphores[virtual_frame_index], VK_NULL_HANDLE, &swapchain_image_index);
+ handle_swapchain_result(acquire_result);
+
+ api.start_record(graphics_command_buffers[virtual_frame_index]);
auto* cmd_buf = graphics_command_buffers[virtual_frame_index];
+ // wait for transfer operations
+
for (auto& renderpass: renderpasses) {
renderpass->execute(*this, cmd_buf);
@@ -193,32 +202,22 @@ void vkrenderer::render() {
api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, swapchain.images[swapchain_image_index]);
- finish_frame();
+ api.end_record(cmd_buf);
+
+ recorded_command_buffers.push_back(cmd_buf);
}
-// private functions
void vkrenderer::begin_frame() {
+ recorded_command_buffers.clear();
VKRESULT(vkWaitForFences(context.device, 1, &submission_fences[virtual_frame_index], VK_TRUE, UINT64_MAX))
VKRESULT(vkResetFences(context.device, 1, &submission_fences[virtual_frame_index]))
- swapchain_image_index = 0;
- auto acquire_result = vkAcquireNextImageKHR(context.device, swapchain.handle, UINT64_MAX, acquire_semaphores[virtual_frame_index], VK_NULL_HANDLE, &swapchain_image_index);
- handle_swapchain_result(acquire_result);
-
- api.start_record(graphics_command_buffers[virtual_frame_index]);
+ update_images();
}
void vkrenderer::finish_frame() {
- auto* cmd_buf = graphics_command_buffers[virtual_frame_index];
-
- // api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, swapchain.images[swapchain_image_index]);
-
- api.end_record(cmd_buf);
-
-
- // TODO: Submit copy command buffer
- api.submit_graphics(cmd_buf, acquire_semaphores[virtual_frame_index], execution_semaphores[virtual_frame_index], submission_fences[virtual_frame_index]);
+ api.submit(recorded_command_buffers.data(), recorded_command_buffers.size(), acquire_semaphores[virtual_frame_index], execution_semaphores[virtual_frame_index], submission_fences[virtual_frame_index]);
auto present_result = api.present(swapchain, swapchain_image_index, execution_semaphores[virtual_frame_index]);
handle_swapchain_result(present_result);
@@ -227,6 +226,8 @@ void vkrenderer::finish_frame() {
}
+
+// private functions
void vkrenderer::handle_swapchain_result(VkResult function_result) {
switch(function_result) {
case VK_ERROR_OUT_OF_DATE_KHR: