aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorladevieq <ladevie.quentin@gmail.com>2022-02-14 12:45:52 +0100
committerladevieq <ladevie.quentin@gmail.com>2022-02-14 12:45:52 +0100
commitf582eb80d73a1d0b735503c8894636782406228c (patch)
treec4eb2da956a5b8977c8796b5fe25725ff518a23f
parentbbb45f80298dc4a41d31805416bad19363c8eff8 (diff)
High level buffer class
-rw-r--r--include/compute-renderpass.hpp29
-rw-r--r--include/renderpass.hpp27
-rw-r--r--include/scene.hpp18
-rw-r--r--include/vk-api.hpp1
-rw-r--r--include/vk-renderer.hpp69
-rw-r--r--src/compute-renderpass.cpp9
-rw-r--r--src/gltf.cpp22
-rw-r--r--src/main.cpp93
-rw-r--r--src/scene.cpp28
-rw-r--r--src/vk-api.cpp55
-rw-r--r--src/vk-renderer.cpp36
11 files changed, 237 insertions, 150 deletions
diff --git a/include/compute-renderpass.hpp b/include/compute-renderpass.hpp
index 39cbf79..a581930 100644
--- a/include/compute-renderpass.hpp
+++ b/include/compute-renderpass.hpp
@@ -1,32 +1,11 @@
#pragma once
+#include "renderpass.hpp"
#include "vk-api.hpp"
#include <array>
class Texture;
-class Renderpass {
- public:
-
- Renderpass(vkapi& api)
- :api(api)
- {};
-
- virtual ~Renderpass() {
- api.destroy_pipeline(pipeline);
- }
-
- void set_pipeline(pipeline pipeline) {
- this->pipeline = pipeline;
- }
-
- // TODO: Do not use vulkan api type
- virtual void execute(VkCommandBuffer command_buffer) = 0;
-
- protected:
- vkapi &api;
-
- pipeline pipeline;
-};
+class Buffer;
class ComputeRenderpass : public Renderpass {
public:
@@ -35,12 +14,16 @@ class ComputeRenderpass : public Renderpass {
: Renderpass(api)
{}
+
+ void set_pipeline(std::string& shader_name) override final;
+
void set_dispatch_size(size_t count_x, size_t count_y, size_t count_z);
void set_ouput_texture(Texture* ouput_texture);
void set_constant(off_t offset, uint64_t* constant);
void set_constant(off_t offset, Texture* texture);
+ void set_constant(off_t offset, Buffer* buffer);
// TODO: Do not use vulkan api type
void execute(VkCommandBuffer command_buffer) override final;
diff --git a/include/renderpass.hpp b/include/renderpass.hpp
new file mode 100644
index 0000000..64947b6
--- /dev/null
+++ b/include/renderpass.hpp
@@ -0,0 +1,27 @@
+#pragma once
+
+#include <string>
+
+#include "vk-api.hpp"
+
+class Renderpass {
+ public:
+
+ Renderpass(vkapi& api)
+ :api(api)
+ {};
+
+ virtual ~Renderpass() {
+ api.destroy_pipeline(pipeline);
+ }
+
+ virtual void set_pipeline(std::string& shader_name) = 0;
+
+ // TODO: Do not use vulkan api type
+ virtual void execute(VkCommandBuffer command_buffer) = 0;
+
+ protected:
+ vkapi &api;
+
+ pipeline pipeline;
+};
diff --git a/include/scene.hpp b/include/scene.hpp
index e24e65f..4bce1a7 100644
--- a/include/scene.hpp
+++ b/include/scene.hpp
@@ -34,10 +34,6 @@ class scene {
public:
scene(camera cam, uint32_t width, uint32_t height, vkrenderer &renderer);
- void* scene_buffer_ptr() {
- return scene_buffer.alloc_info.pMappedData;
- }
-
metadata meta;
// Geometry & BVH
@@ -47,13 +43,13 @@ public:
std::vector<float> uvs;
std::vector<material> materials;
- buffer scene_buffer;
- buffer indices_buffer;
- buffer positions_buffer;
- buffer normals_buffer;
- buffer uvs_buffer;
- buffer bvh_buffer;
- buffer materials_buffer;
+ Buffer* scene_buffer;
+ Buffer* indices_buffer;
+ Buffer* positions_buffer;
+ Buffer* normals_buffer;
+ Buffer* uvs_buffer;
+ Buffer* bvh_buffer;
+ Buffer* materials_buffer;
std::vector<packed_bvh_node> packed_nodes;
};
diff --git a/include/vk-api.hpp b/include/vk-api.hpp
index 174d050..cc0188d 100644
--- a/include/vk-api.hpp
+++ b/include/vk-api.hpp
@@ -159,6 +159,7 @@ class vkapi {
void update_descriptor_image(image &img, VkDescriptorType type);
void update_descriptor_images(std::vector<image> &images, VkDescriptorType type);
+ void update_descriptor_sampler(sampler &sampler);
void update_descriptor_samplers(std::vector<sampler> &samplers);
diff --git a/include/vk-renderer.hpp b/include/vk-renderer.hpp
index ba9b5a0..76dfffc 100644
--- a/include/vk-renderer.hpp
+++ b/include/vk-renderer.hpp
@@ -1,21 +1,20 @@
#ifndef __VK_RENDERER_HPP_
#define __VK_RENDERER_HPP_
+#include <stdint.h>
#include <vector>
#include "vk-api.hpp"
-#include "vulkan-loader.hpp"
+#include "vulkan/vulkan_core.h"
-#include "compute-renderpass.hpp"
-class scene;
+class Renderpass;
+class ComputeRenderpass;
class window;
-class Texture {
- public:
-
- image device_image;
-};
+class Texture;
+class Buffer;
+class Sampler;
class vkrenderer {
public:
@@ -33,19 +32,26 @@ class vkrenderer {
void recreate_swapchain();
- void update_image(image img, void* data, size_t size);
+ void update_image(Texture* texture, void* data, size_t size);
- Texture* create_2d_texture(size_t width, size_t height);
+ Buffer* create_buffer(size_t size, bool isStatic);
+
+ Texture* create_2d_texture(size_t width, size_t height, VkFormat format);
+
+ Sampler* create_sampler(VkFilter filter, VkSamplerAddressMode address_mode);
ComputeRenderpass* create_compute_renderpass();
void render();
+ uint32_t frame_index() { return this->virtual_frame_index; }
+
+ private:
+
vkapi api;
std::vector<Renderpass*> renderpasses;
- private:
void handle_swapchain_result(VkResult function_result);
@@ -81,4 +87,45 @@ class vkrenderer {
static constexpr uint32_t virtual_frames_count = 2;
};
+// TODO: Move those to there own files
+class Texture {
+ public:
+
+ sampler sampler;
+
+ image device_image;
+};
+
+class Sampler {
+ public:
+ sampler device_sampler;
+};
+
+class Buffer {
+ public:
+
+ Buffer(vkrenderer* renderer, size_t size, bool isStatic)
+ : renderer(renderer), size(size), isStatic(isStatic) {}
+
+ void* ptr() {
+ size_t offset = isStatic ? 0 : size * renderer->frame_index();
+ return (uint8_t*)device_buffer.alloc_info.pMappedData + offset;
+ }
+
+ unsigned long long device_address() {
+ size_t offset = isStatic ? 0 : size * renderer->frame_index();
+ return device_buffer.device_address + offset;
+ }
+
+ buffer device_buffer;
+
+ private:
+
+ bool isStatic;
+
+ size_t size;
+
+ vkrenderer* renderer;
+};
+
#endif // !__VK_RENDERER_HPP_
diff --git a/src/compute-renderpass.cpp b/src/compute-renderpass.cpp
index 8fd4895..d801b11 100644
--- a/src/compute-renderpass.cpp
+++ b/src/compute-renderpass.cpp
@@ -4,6 +4,10 @@
#include "vk-renderer.hpp"
+void ComputeRenderpass::set_pipeline(std::string& shader_name) {
+ this->pipeline = api.create_compute_pipeline(shader_name.c_str());
+}
+
void ComputeRenderpass::set_ouput_texture(Texture* output_texture) {
this->output_texture = output_texture;
@@ -27,6 +31,11 @@ void ComputeRenderpass::set_constant(off_t offset, Texture* texture) {
input_textures.push_back(texture);
}
+void ComputeRenderpass::set_constant(off_t offset, Buffer* buffer) {
+ auto address = buffer->device_address();
+ memcpy(constants.data() + offset, (void*)&address, 8);
+}
+
void ComputeRenderpass::execute(VkCommandBuffer command_buffer) {
vkCmdPushConstants(command_buffer, api.bindless_descriptor.pipeline_layout, VK_SHADER_STAGE_COMPUTE_BIT, 0, 64, (void*)&constants);
diff --git a/src/gltf.cpp b/src/gltf.cpp
index 61c68ac..b05e71e 100644
--- a/src/gltf.cpp
+++ b/src/gltf.cpp
@@ -84,19 +84,15 @@ std::vector<mesh> gltf::load_meshes(json &gltf_json, std::vector<std::vector<uin
std::vector<texture> gltf::load_textures(json &gltf_json, std::filesystem::path &path, vkrenderer &renderer) {
auto &gltf_images = gltf_json["images"];
auto images_count = gltf_images.size();
- std::vector<image> images { images_count };
+ std::vector<Texture*> images { images_count };
for (size_t image_index = 0; image_index < images_count; image_index++) {
auto &gltf_image = gltf_images[image_index];
int x,y,n;
auto filepath = (path / gltf_image["uri"].get<std::string>()).string();
unsigned char *data = stbi_load(filepath.c_str(), &x, &y, &n, 4);
- VkExtent3D size {
- .width = static_cast<uint32_t>(x),
- .height = static_cast<uint32_t>(y),
- .depth = 1
- };
- auto img = renderer.api.create_image(size, VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
+ auto img = renderer.create_2d_texture(static_cast<uint32_t>(x), static_cast<uint32_t>(y), VK_FORMAT_R8G8B8A8_UNORM);
+
renderer.update_image(img, data, x * y * 4);
stbi_image_free(data);
@@ -104,18 +100,14 @@ std::vector<texture> gltf::load_textures(json &gltf_json, std::filesystem::path
images[image_index] = std::move(img);
}
- renderer.api.update_descriptor_images(images, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
-
auto &gltf_samplers = gltf_json["samplers"];
auto samplers_count = gltf_samplers.size();
- std::vector<sampler> samplers { samplers_count };
+ std::vector<Sampler*> samplers { samplers_count };
for (size_t sampler_index = 0; sampler_index < samplers_count; sampler_index++) {
- samplers[sampler_index] = renderer.api.create_sampler(VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_REPEAT);
+ samplers[sampler_index] = renderer.create_sampler(VK_FILTER_LINEAR, VK_SAMPLER_ADDRESS_MODE_REPEAT);
}
- renderer.api.update_descriptor_samplers(samplers);
-
auto &gltf_textures = gltf_json["textures"];
auto textures_count = gltf_textures.size();
std::vector<texture> textures { textures_count };
@@ -130,11 +122,11 @@ std::vector<texture> gltf::load_textures(json &gltf_json, std::filesystem::path
if (gltf_texture.contains("sampler")) {
auto sampler_index = gltf_texture["sampler"].get<uint32_t>();
auto &sampler = samplers[sampler_index];
- sampler_id = sampler.bindless_index;
+ sampler_id = sampler->device_sampler.bindless_index;
}
textures[texture_index] = texture {
- .image_id = image.bindless_sampled_index,
+ .image_id = image->device_image.bindless_sampled_index,
.sampler_id = sampler_id
};
}
diff --git a/src/main.cpp b/src/main.cpp
index 4b8edad..197c794 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -7,8 +7,8 @@
#include "thirdparty/renderdoc.h"
#include "imgui.h"
+#include "compute-renderpass.hpp"
#include "vk-renderer.hpp"
-#include "vulkan-loader.hpp"
#include "window.hpp"
#include "scene.hpp"
#include "defines.hpp"
@@ -66,18 +66,18 @@ int main() {
auto main_scene = scene(cam, width, height, renderer);
+ std::string raytracing_shader_name = "compute";
auto raytracing_pass = renderer.create_compute_renderpass();
- raytracing_pass->set_pipeline(renderer.api.create_compute_pipeline("compute"));
+ raytracing_pass->set_pipeline(raytracing_shader_name);
- auto* accumulation_texture = renderer.create_2d_texture(width, height);
- auto* output_texture = renderer.create_2d_texture(width, height);
- raytracing_pass->set_constant(0, &main_scene.scene_buffer.device_address);
- raytracing_pass->set_constant(8, &main_scene.bvh_buffer.device_address);
- raytracing_pass->set_constant(16, &main_scene.indices_buffer.device_address);
- raytracing_pass->set_constant(24, &main_scene.positions_buffer.device_address);
- raytracing_pass->set_constant(32, &main_scene.normals_buffer.device_address);
- raytracing_pass->set_constant(40, &main_scene.uvs_buffer.device_address);
- raytracing_pass->set_constant(48, &main_scene.materials_buffer.device_address);
+ auto* accumulation_texture = renderer.create_2d_texture(width, height, VK_FORMAT_R32G32B32A32_SFLOAT);
+ auto* output_texture = renderer.create_2d_texture(width, height, VK_FORMAT_R32G32B32A32_SFLOAT);
+ raytracing_pass->set_constant(8, main_scene.bvh_buffer);
+ raytracing_pass->set_constant(16, main_scene.indices_buffer);
+ raytracing_pass->set_constant(24, main_scene.positions_buffer);
+ raytracing_pass->set_constant(32, main_scene.normals_buffer);
+ raytracing_pass->set_constant(40, main_scene.uvs_buffer);
+ raytracing_pass->set_constant(48, main_scene.materials_buffer);
auto can_render = true;
@@ -87,8 +87,6 @@ int main() {
io.DisplaySize.y = (float)height;
while(wnd.isOpen) {
- auto reset_accumulation = false;
-
end = std::chrono::high_resolution_clock::now();
delta_time = std::chrono::duration<float, std::milli>(end - start).count();
@@ -106,8 +104,8 @@ int main() {
width = event.width;
height = event.height;
- ((scene*) main_scene.scene_buffer_ptr())->meta.width = width;
- ((scene*) main_scene.scene_buffer_ptr())->meta.height = height;
+ main_scene.meta.width = width;
+ main_scene.meta.height = height;
io.DisplaySize.x = (float)width;
io.DisplaySize.y = (float)height;
@@ -117,15 +115,15 @@ int main() {
} else {
can_render = true;
renderer.recreate_swapchain();
- ((scene*) main_scene.scene_buffer_ptr())->meta.cam.set_aspect_ratio((float)event.width / (float)event.height);
- ((scene*) main_scene.scene_buffer_ptr())->meta.sample_index = 0;
+ main_scene.meta.cam.set_aspect_ratio((float)event.width / (float)event.height);
+ main_scene.meta.sample_index = 0;
- accumulation_texture = renderer.create_2d_texture(width, height);
- output_texture = renderer.create_2d_texture(width, height);
+ accumulation_texture = renderer.create_2d_texture(width, height, VK_FORMAT_R32G32B32A32_SFLOAT);
+ output_texture = renderer.create_2d_texture(width, height, VK_FORMAT_R32G32B32A32_SFLOAT);
raytracing_pass->set_dispatch_size(event.width / 8 + 1, event.height / 8 + 1, 1);
}
- reset_accumulation = true;
+ main_scene.meta.sample_index = 0;
break;
}
@@ -139,47 +137,47 @@ int main() {
switch (event.key) {
case KEYS::W: {
- move_vec = ((scene*) main_scene.scene_buffer_ptr())->meta.cam.forward * move_speed;
+ move_vec = main_scene.meta.cam.forward * move_speed;
break;
}
case KEYS::S: {
- move_vec = -((scene*) main_scene.scene_buffer_ptr())->meta.cam.forward * move_speed;
+ move_vec = -main_scene.meta.cam.forward * move_speed;
break;
}
case KEYS::D: {
- move_vec = ((scene*) main_scene.scene_buffer_ptr())->meta.cam.right * move_speed;
+ move_vec = main_scene.meta.cam.right * move_speed;
break;
}
case KEYS::A: {
- move_vec = -((scene*) main_scene.scene_buffer_ptr())->meta.cam.right * move_speed;
+ move_vec = -main_scene.meta.cam.right * move_speed;
break;
}
case KEYS::E: {
- ((scene*) main_scene.scene_buffer_ptr())->meta.cam.rotate_y(0.001f * delta_time);
- reset_accumulation = true;
+ main_scene.meta.cam.rotate_y(0.001f * delta_time);
+ main_scene.meta.sample_index = 0;
break;
}
case KEYS::Q: {
- ((scene*) main_scene.scene_buffer_ptr())->meta.cam.rotate_y(-0.001f * delta_time);
- reset_accumulation = true;
+ main_scene.meta.cam.rotate_y(-0.001f * delta_time);
+ main_scene.meta.sample_index = 0;
break;
}
case KEYS::SPACE: {
- move_vec = ((scene*) main_scene.scene_buffer_ptr())->meta.cam.up * move_speed;
+ move_vec = main_scene.meta.cam.up * move_speed;
break;
}
case KEYS::LCTRL: {
- move_vec = -((scene*) main_scene.scene_buffer_ptr())->meta.cam.up * move_speed;
+ move_vec = -main_scene.meta.cam.up * move_speed;
break;
}
default:
break;
}
- ((scene*) main_scene.scene_buffer_ptr())->meta.cam.move(move_vec);
+ main_scene.meta.cam.move(move_vec);
if (!move_vec.near_zero()) {
- reset_accumulation = true;
+ main_scene.meta.sample_index = 0;
}
break;
@@ -225,20 +223,20 @@ int main() {
ImGui::Text("frame per second %u\n", static_cast<uint32_t>(1000.f / delta_time));
ImGui::Text("frame time %f ms\n", delta_time);
- ImGui::Text("frame count %u\n", ((scene*) main_scene.scene_buffer_ptr())->meta.sample_index);
+ ImGui::Text("frame count %u\n", main_scene.meta.sample_index);
- if (ImGui::Checkbox("depth of field", (bool*)&((scene*) main_scene.scene_buffer_ptr())->meta.enable_dof)) {
- reset_accumulation = true;
+ if (ImGui::Checkbox("depth of field", (bool*)&main_scene.meta.enable_dof)) {
+ main_scene.meta.sample_index = 0;
}
- ImGui::SliderInt("max bounces", (int32_t*)&((scene*) main_scene.scene_buffer_ptr())->meta.max_bounce, 1, 250);
- ImGui::SliderInt("min bounces", (int32_t*)&((scene*) main_scene.scene_buffer_ptr())->meta.min_bounce, 1, ((scene*) main_scene.scene_buffer_ptr())->meta.max_bounce);
- if (ImGui::SliderInt("downscale factor", (int32_t*)&((scene*) main_scene.scene_buffer_ptr())->meta.downscale_factor, 1, 32)) {
- reset_accumulation = true;
+ ImGui::SliderInt("max bounces", (int32_t*)&main_scene.meta.max_bounce, 1, 250);
+ ImGui::SliderInt("min bounces", (int32_t*)&main_scene.meta.min_bounce, 1, main_scene.meta.max_bounce);
+ if (ImGui::SliderInt("downscale factor", (int32_t*)&main_scene.meta.downscale_factor, 1, 32)) {
+ main_scene.meta.sample_index = 0;
}
- if (ImGui::Checkbox("debug bvh", (bool*)&((scene*) main_scene.scene_buffer_ptr())->meta.debug_bvh)) {
- reset_accumulation = true;
+ if (ImGui::Checkbox("debug bvh", (bool*)&main_scene.meta.debug_bvh)) {
+ main_scene.meta.sample_index = 0;
}
ImGui::End();
@@ -251,22 +249,17 @@ int main() {
// See the documentation below for a longer explanation
// if(rdoc_api) rdoc_api->StartFrameCapture(NULL, NULL);
- // float scale = (float)((scene*) main_scene.scene_buffer_ptr())->meta.downscale_factor;
- // renderer.compute(width / scale, height / scale);
-
- // ((scene*) main_scene.scene_buffer_ptr())->meta.sample_index++;
-
// renderer.ui();
if (can_render) {
+ std::memcpy(main_scene.scene_buffer->ptr(), &main_scene.meta, sizeof(main_scene.meta));
+
raytracing_pass->set_ouput_texture(output_texture);
+ raytracing_pass->set_constant(0, main_scene.scene_buffer);
raytracing_pass->set_constant(60, accumulation_texture);
- if (reset_accumulation) {
- ((scene*) main_scene.scene_buffer_ptr())->meta.sample_index = 0;
- }
- ((scene*) main_scene.scene_buffer_ptr())->meta.sample_index++;
+ main_scene.meta.sample_index++;
renderer.render();
diff --git a/src/scene.cpp b/src/scene.cpp
index f538292..44c8f8e 100644
--- a/src/scene.cpp
+++ b/src/scene.cpp
@@ -123,24 +123,24 @@ scene::scene(camera cam, uint32_t width, uint32_t height, vkrenderer &renderer)
bvh builder(triangles, packed_nodes);
// bvh builder(spheres, packed_nodes);
- scene_buffer = renderer.api.create_buffer(sizeof(meta), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU);
- std::memcpy(scene_buffer.alloc_info.pMappedData, &meta, sizeof(meta));
+ scene_buffer = renderer.create_buffer(sizeof(meta), false);
+ std::memcpy(scene_buffer->ptr(), &meta, sizeof(meta));
- indices_buffer = renderer.api.create_buffer(indices.size() * sizeof(indices[0]), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU);
- std::memcpy(indices_buffer.alloc_info.pMappedData, indices.data(), indices.size() * sizeof(indices[0]));
+ indices_buffer = renderer.create_buffer(indices.size() * sizeof(indices[0]), true);
+ std::memcpy(indices_buffer->ptr(), indices.data(), indices.size() * sizeof(indices[0]));
- positions_buffer = renderer.api.create_buffer(positions.size() * sizeof(positions[0]), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU);
- std::memcpy(positions_buffer.alloc_info.pMappedData, positions.data(), positions.size() * sizeof(positions[0]));
+ positions_buffer = renderer.create_buffer(positions.size() * sizeof(positions[0]), true);
+ std::memcpy(positions_buffer->ptr(), positions.data(), positions.size() * sizeof(positions[0]));
- normals_buffer = renderer.api.create_buffer(normals.size() * sizeof(normals[0]), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU);
- std::memcpy(normals_buffer.alloc_info.pMappedData, normals.data(), normals.size() * sizeof(normals[0]));
+ normals_buffer = renderer.create_buffer(normals.size() * sizeof(normals[0]), true);
+ std::memcpy(normals_buffer->ptr(), normals.data(), normals.size() * sizeof(normals[0]));
- uvs_buffer = renderer.api.create_buffer(uvs.size() * sizeof(uvs[0]), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU);
- std::memcpy(uvs_buffer.alloc_info.pMappedData, uvs.data(), uvs.size() * sizeof(uvs[0]));
+ uvs_buffer = renderer.create_buffer(uvs.size() * sizeof(uvs[0]), true);
+ std::memcpy(uvs_buffer->ptr(), uvs.data(), uvs.size() * sizeof(uvs[0]));
- bvh_buffer = renderer.api.create_buffer(packed_nodes.size() * sizeof(packed_nodes[0]), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU);
- std::memcpy(bvh_buffer.alloc_info.pMappedData, packed_nodes.data(), packed_nodes.size() * sizeof(packed_nodes[0]));
+ bvh_buffer = renderer.create_buffer(packed_nodes.size() * sizeof(packed_nodes[0]), true);
+ std::memcpy(bvh_buffer->ptr(), packed_nodes.data(), packed_nodes.size() * sizeof(packed_nodes[0]));
- materials_buffer = renderer.api.create_buffer(materials.size() * sizeof(materials[0]), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU);
- std::memcpy(materials_buffer.alloc_info.pMappedData, materials.data(), materials.size() * sizeof(materials[0]));
+ materials_buffer = renderer.create_buffer(materials.size() * sizeof(materials[0]), true);
+ std::memcpy(materials_buffer->ptr(), materials.data(), materials.size() * sizeof(materials[0]));
}
diff --git a/src/vk-api.cpp b/src/vk-api.cpp
index 27d0da7..a5f6435 100644
--- a/src/vk-api.cpp
+++ b/src/vk-api.cpp
@@ -1,6 +1,5 @@
#include <cassert>
#include <memory>
-#include <iostream>
#include "vk-api.hpp"
#include "window.hpp"
@@ -902,25 +901,25 @@ void vkapi::destroy_swapchain(swapchain& swapchain) {
void vkapi::update_descriptor_image(image &img, VkDescriptorType type) {
- VkDescriptorImageInfo descriptor_images_info;
- VkWriteDescriptorSet writes_descriptor;
+ VkDescriptorImageInfo descriptor_image_info;
+ VkWriteDescriptorSet write_descriptor;
- descriptor_images_info.sampler = VK_NULL_HANDLE;
- descriptor_images_info.imageView = img.view;
- descriptor_images_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
+ descriptor_image_info.sampler = VK_NULL_HANDLE;
+ descriptor_image_info.imageView = img.view;
+ descriptor_image_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
- writes_descriptor.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
- writes_descriptor.pNext = nullptr;
- writes_descriptor.dstSet = bindless_descriptor.set;
- writes_descriptor.dstBinding = type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ? 2 : 1;
- writes_descriptor.dstArrayElement = type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ? img.bindless_storage_index : img.bindless_sampled_index;
- writes_descriptor.descriptorCount = 1;
- writes_descriptor.descriptorType = type;
- writes_descriptor.pImageInfo = &descriptor_images_info;
- writes_descriptor.pBufferInfo = VK_NULL_HANDLE;
- writes_descriptor.pTexelBufferView = VK_NULL_HANDLE;
+ write_descriptor.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+ write_descriptor.pNext = nullptr;
+ write_descriptor.dstSet = bindless_descriptor.set;
+ write_descriptor.dstBinding = type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ? 2 : 1;
+ write_descriptor.dstArrayElement = type == VK_DESCRIPTOR_TYPE_STORAGE_IMAGE ? img.bindless_storage_index : img.bindless_sampled_index;
+ write_descriptor.descriptorCount = 1;
+ write_descriptor.descriptorType = type;
+ write_descriptor.pImageInfo = &descriptor_image_info;
+ write_descriptor.pBufferInfo = VK_NULL_HANDLE;
+ write_descriptor.pTexelBufferView = VK_NULL_HANDLE;
- vkUpdateDescriptorSets(context.device, 1, &writes_descriptor, 0, nullptr);
+ vkUpdateDescriptorSets(context.device, 1, &write_descriptor, 0, nullptr);
}
void vkapi::update_descriptor_images(std::vector<image> &images, VkDescriptorType type) {
@@ -948,6 +947,28 @@ void vkapi::update_descriptor_images(std::vector<image> &images, VkDescriptorTyp
vkUpdateDescriptorSets(context.device, writes_descriptor.size(), writes_descriptor.data(), 0, nullptr);
}
+void vkapi::update_descriptor_sampler(sampler &sampler) {
+ VkDescriptorImageInfo descriptor_image_info;
+ VkWriteDescriptorSet write_descriptor;
+
+ descriptor_image_info.sampler = sampler.handle;
+ descriptor_image_info.imageView = VK_NULL_HANDLE;
+ descriptor_image_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
+
+ write_descriptor.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+ write_descriptor.pNext = nullptr;
+ write_descriptor.dstSet = bindless_descriptor.set;
+ write_descriptor.dstBinding = 0;
+ write_descriptor.dstArrayElement = sampler.bindless_index;
+ write_descriptor.descriptorCount = 1;
+ write_descriptor.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER;
+ write_descriptor.pImageInfo = &descriptor_image_info;
+ write_descriptor.pBufferInfo = VK_NULL_HANDLE;
+ write_descriptor.pTexelBufferView = VK_NULL_HANDLE;
+
+ vkUpdateDescriptorSets(context.device, 1, &write_descriptor, 0, nullptr);
+}
+
void vkapi::update_descriptor_samplers(std::vector<sampler> &samplers) {
std::vector<VkDescriptorImageInfo> descriptor_images_info { samplers.size() };
std::vector<VkWriteDescriptorSet> writes_descriptor { samplers.size() };
diff --git a/src/vk-renderer.cpp b/src/vk-renderer.cpp
index b449d81..8eb2f57 100644
--- a/src/vk-renderer.cpp
+++ b/src/vk-renderer.cpp
@@ -8,8 +8,6 @@
#include "thirdparty/vk_mem_alloc.h"
#include "defines.hpp"
-#include "scene.hpp"
-#include "vulkan/vulkan_core.h"
#include "window.hpp"
#ifdef _DEBUG
@@ -342,7 +340,7 @@ void vkrenderer::handle_swapchain_result(VkResult function_result) {
}
}
-void vkrenderer::update_image(image img, void* data, size_t size) {
+void vkrenderer::update_image(Texture* texture, void* data, size_t size) {
if (staging_buffer.size < size) {
api.destroy_buffer(staging_buffer);
@@ -357,11 +355,11 @@ void vkrenderer::update_image(image img, void* data, size_t size) {
auto cmd_buf = command_buffers[virtual_frame_index];
api.start_record(cmd_buf);
- api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, img);
+ api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, texture->device_image);
- api.copy_buffer(cmd_buf, staging_buffer, img);
+ api.copy_buffer(cmd_buf, staging_buffer, texture->device_image);
- api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_GENERAL, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, img);
+ api.image_barrier(cmd_buf, VK_IMAGE_LAYOUT_GENERAL, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, texture->device_image);
api.end_record(cmd_buf);
@@ -372,19 +370,39 @@ void vkrenderer::update_image(image img, void* data, size_t size) {
}
-Texture* vkrenderer::create_2d_texture(size_t width, size_t height) {
+Buffer* vkrenderer::create_buffer(size_t size, bool isStatic) {
+ auto buffer = new Buffer(this, size, isStatic);
+
+ buffer->device_buffer = api.create_buffer(isStatic ? size : size * virtual_frames_count, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU);
+
+ return buffer;
+}
+
+Texture* vkrenderer::create_2d_texture(size_t width, size_t height, VkFormat format) {
auto texture = new Texture();
texture->device_image = api.create_image(
{ .width = (uint32_t)width, .height = (uint32_t)height, .depth = 1 },
- VK_FORMAT_R32G32B32A32_SFLOAT,
- VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT
+ format,
+ VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT
);
api.update_descriptor_image(texture->device_image, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
+ api.update_descriptor_image(texture->device_image, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
return texture;
}
+// TODO: Check if a similar sampler has been allocated
+Sampler* vkrenderer::create_sampler(VkFilter filter, VkSamplerAddressMode address_mode) {
+ auto sampler = new Sampler();
+
+ sampler->device_sampler = api.create_sampler(filter, address_mode);
+
+ api.update_descriptor_sampler(sampler->device_sampler);
+
+ return sampler;
+}
+
ComputeRenderpass* vkrenderer::create_compute_renderpass() {
renderpasses.push_back(new ComputeRenderpass(api));