aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorladevieq <ladevie.quentin@gmail.com>2026-08-18 00:43:03 +0200
committerladevieq <ladevie.quentin@gmail.com>2026-08-18 00:43:03 +0200
commit6db256b8eb4cc45c5296070ae7353e65398d121d (patch)
tree0df44bebae817cbc575dbd288f4bb08a08767873
parent0c7ff7a068958d2c23a8f362763cb22d34f32371 (diff)
Finished descriptor heaps implementation
-rw-r--r--include/scene.hpp12
-rw-r--r--include/vk-bindless.hpp49
-rw-r--r--include/vk-device.hpp26
-rw-r--r--shaders/api-test-ui.frag25
-rw-r--r--shaders/compute.comp54
-rw-r--r--shaders/include/ray.h54
-rw-r--r--shaders/test.comp20
-rw-r--r--shaders/tonemapping.comp38
-rw-r--r--shaders/transmittance_lut.comp7
-rw-r--r--src/main.cpp191
-rw-r--r--src/scene.cpp59
-rw-r--r--src/vk-bindless.cpp238
-rw-r--r--src/vk-command-buffer.cpp88
-rw-r--r--src/vk-device.cpp183
14 files changed, 341 insertions, 703 deletions
diff --git a/include/scene.hpp b/include/scene.hpp
index a1c76e2..5cda832 100644
--- a/include/scene.hpp
+++ b/include/scene.hpp
@@ -38,12 +38,12 @@ public:
handle<device_buffer> bvh_buffer_handle;
handle<device_buffer> materials_buffer_handle;
- uint64_t indices_buffer_address() { return vkdevice::get().get_buffer(indices_buffer_handle).device_address; };
- uint64_t positions_buffer_address() { return vkdevice::get().get_buffer(positions_buffer_handle).device_address; };
- uint64_t normals_buffer_address() { return vkdevice::get().get_buffer(normals_buffer_handle).device_address; };
- uint64_t uvs_buffer_address() { return vkdevice::get().get_buffer(uvs_buffer_handle).device_address; };
- uint64_t bvh_buffer_address() { return vkdevice::get().get_buffer(bvh_buffer_handle).device_address; };
- uint64_t materials_buffer_address() { return vkdevice::get().get_buffer(materials_buffer_handle).device_address; };
+ uint64_t indices_buffer_address() { return vkdevice::get().get_buffer(indices_buffer_handle)->device_address; };
+ uint64_t positions_buffer_address() { return vkdevice::get().get_buffer(positions_buffer_handle)->device_address; };
+ uint64_t normals_buffer_address() { return vkdevice::get().get_buffer(normals_buffer_handle)->device_address; };
+ uint64_t uvs_buffer_address() { return vkdevice::get().get_buffer(uvs_buffer_handle)->device_address; };
+ uint64_t bvh_buffer_address() { return vkdevice::get().get_buffer(bvh_buffer_handle)->device_address; };
+ uint64_t materials_buffer_address() { return vkdevice::get().get_buffer(materials_buffer_handle)->device_address; };
};
#endif // !__SCENE_HPP_
diff --git a/include/vk-bindless.hpp b/include/vk-bindless.hpp
deleted file mode 100644
index be076b8..0000000
--- a/include/vk-bindless.hpp
+++ /dev/null
@@ -1,49 +0,0 @@
-#pragma once
-
-#include <vulkan/vulkan_core.h>
-
-#include "handle.hpp"
-
-enum UniformTypes : uint32_t {
- GLOBAL,
- PASS,
- DRAW,
- MAX,
-};
-
-enum SamplerType : uint32_t {
- NEAREST,
- LINEAR,
- MAX_SAMPLER,
-};
-
-struct device_buffer;
-
-struct bindless_model {
- [[nodiscard]] device_buffer* get_uniform_buffer(enum UniformTypes type) const;
-
- void init();
-
- void deinit();
-
- VkPipelineLayout global_layout;
- VkDescriptorSet global_set;
-
-public:
- static constexpr size_t push_constant_slot_size = sizeof(uintptr_t);
- static constexpr size_t push_constant_slots = 3U;
-
-private:
- VkDescriptorSetLayout global_set_layout;
- VkDescriptorPool descriptor_pool;
- handle<device_buffer> uniform_buffers[UniformTypes::MAX];
-
- static constexpr size_t descriptor_pool_allocable_sets_count = 64U;
- static constexpr uint32_t set_descriptors_count = 1024U;
-
- VkSampler samplers[SamplerType::MAX_SAMPLER];
-
- static constexpr size_t globals_uniform_buffer_size = 64 * KB;
- static constexpr size_t passes_uniform_buffer_size = 64 * KB;
- static constexpr size_t draws_uniform_buffer_size = 64 * KB;
-};
diff --git a/include/vk-device.hpp b/include/vk-device.hpp
index 84a1a36..913a28b 100644
--- a/include/vk-device.hpp
+++ b/include/vk-device.hpp
@@ -1,7 +1,6 @@
#pragma once
#include "freelist.hpp"
-#include "vk-bindless.hpp"
#include "vk-command-buffer.hpp"
using VmaAllocator = struct VmaAllocator_T*;
@@ -72,14 +71,6 @@ class vkdevice {
return &surfaces[handle];
}
- inline VmaAllocator get_allocator() const {
- return gpu_allocator;
- }
-
- inline VkDevice get_device() const {
- return device;
- }
-
// uint64_t submit(std::span<command_buffer> buffers, handle<device_semaphore> wait_handle, handle<device_semaphore> signal_handle, handle<device_semaphore> fence_handle);
uint32_t acquire_image_index(handle<device_surface> surface_handle);
uint64_t submit_before_present(handle<device_surface> surface_handle, command_buffer* buffers, uint32_t count);
@@ -104,27 +95,10 @@ class vkdevice {
void create_device();
- void create_heaps(VkPhysicalDeviceDescriptorHeapPropertiesEXT& descriptor_heap_props);
-
bool device_support_features(VkPhysicalDevice physical_dev);
queue queues[static_cast<uint32_t>(QueueType::MAX)];
- VkInstance instance;
- VkPhysicalDevice physical_device;
- VkPhysicalDeviceProperties2 physical_device_props;
- VkDevice device;
-
- handle<device_buffer> image_heap; // TODO: Dont use handle for internally used resources
- handle<device_buffer> sampler_heap;
-
- static constexpr size_t max_images_count = UINT16_MAX;
- static constexpr size_t max_samplers_count = 16U;
-
- static size_t
-
- VmaAllocator gpu_allocator;
-
static constexpr size_t max_allocable_command_buffers = 16;
static constexpr size_t max_submitable_command_buffers = 16;
diff --git a/shaders/api-test-ui.frag b/shaders/api-test-ui.frag
index 8da6369..ad2ea21 100644
--- a/shaders/api-test-ui.frag
+++ b/shaders/api-test-ui.frag
@@ -1,5 +1,6 @@
#extension GL_EXT_buffer_reference : require
#extension GL_EXT_nonuniform_qualifier : require
+#extension GL_EXT_descriptor_heap : require
layout(location = 0) out vec4 o_Color;
@@ -8,17 +9,9 @@ layout(location = 0) in struct {
vec4 color;
} In;
-layout(set = 0, binding = 0) uniform sampler samplers[];
-layout(set = 0, binding = 1) uniform texture2D textures[];
-layout(set = 0, binding = 2, rgba32f) uniform image2D images[];
-
-layout(buffer_reference) readonly buffer global_params {
- uint padding;
-};
-
-layout(buffer_reference) readonly buffer pass_params {
- uint padding;
-};
+layout(descriptor_heap) uniform texture2D textures[];
+layout(descriptor_heap, rgba32f) uniform image2D images[];
+layout(descriptor_heap) uniform sampler samplers[];
struct vertex {
float pos_x;
@@ -32,19 +25,13 @@ layout(buffer_reference) readonly buffer vertices {
vertex vertices[];
};
-layout(buffer_reference) readonly buffer draw_params {
+layout(push_constant) uniform registers {
vertices vertex_buffer;
vec2 scale;
vec2 translate;
uint texture_index;
-};
-
-layout(push_constant) uniform registers {
- global_params globals;
- pass_params pass;
- draw_params draw;
} regs;
void main() {
- o_Color = In.color * texture(sampler2D(textures[nonuniformEXT(regs.draw.texture_index)], samplers[nonuniformEXT(0U)]), In.uv.xy);
+ o_Color = In.color * texture(sampler2D(textures[nonuniformEXT(regs.texture_index)], samplers[nonuniformEXT(0U)]), In.uv.xy);
}
diff --git a/shaders/compute.comp b/shaders/compute.comp
index 934ff70..c361c43 100644
--- a/shaders/compute.comp
+++ b/shaders/compute.comp
@@ -5,6 +5,7 @@
#extension GL_EXT_buffer_reference : require
#extension GL_EXT_nonuniform_qualifier : require
+#extension GL_EXT_descriptor_heap : require
#include "math.h"
#include "color_utils.h"
@@ -90,7 +91,11 @@ layout(buffer_reference) readonly buffer nodes_array {
bvh_node[] nodes;
};
-layout(buffer_reference) readonly buffer global_params {
+layout(descriptor_heap) uniform texture2D textures[];
+layout(descriptor_heap, rgba32f) uniform image2D images[];
+layout(descriptor_heap) uniform sampler samplers[];
+
+layout(push_constant) uniform registers {
camera cam;
uint max_bounce;
@@ -102,13 +107,7 @@ layout(buffer_reference) readonly buffer global_params {
uint enable_dof;
uint debug_bvh;
int downscale_factor;
-};
-
-layout(buffer_reference) readonly buffer pass_params {
- uint padding;
-};
-layout(buffer_reference) readonly buffer draw_params {
nodes_array bvh;
indices_array indices_arr;
positions_array positions_arr;
@@ -117,17 +116,6 @@ layout(buffer_reference) readonly buffer draw_params {
materials_array materials_arr;
uint output_image_index;
uint accumulation_image_index;
- uint padding[2];
-};
-
-layout(set = 0, binding = 0) uniform sampler samplers[];
-layout(set = 0, binding = 1) uniform texture2D textures[];
-layout(set = 0, binding = 2, rgba32f) uniform image2D images[];
-
-layout(push_constant) uniform registers {
- global_params globals;
- pass_params pass;
- draw_params draw;
} regs;
#include "ray.h"
@@ -137,7 +125,7 @@ vec3 ray_color(ray r, uint seed) {
vec3 radiance = vec3(0.0);
vec3 throughput = vec3(1.0);
- for (uint bounce = 0; bounce < regs.globals.max_bounce; bounce++) {
+ for (uint bounce = 0; bounce < regs.max_bounce; bounce++) {
if (!hit_node(r, info))
return throughput * vec3(1.0);
@@ -247,7 +235,7 @@ vec3 ray_color(ray r, uint seed) {
// Russian Roulette
// As the throughput gets smaller, the ray is more likely to get terminated early.
// Survivors have their value boosted to make up for fewer samples being in the average.
- if (bounce > regs.globals.min_bounce) {
+ if (bounce > regs.min_bounce) {
float probability = min(0.95f, luminance(throughput));
if (probability < rand(seed)) break;
throughput /= probability;
@@ -258,42 +246,42 @@ vec3 ray_color(ray r, uint seed) {
}
ray generate_camera_ray(ivec2 coords, uint seed) {
- vec2 scene_size = vec2(regs.globals.width - 1, regs.globals.height - 1);
+ vec2 scene_size = vec2(regs.width - 1, regs.height - 1);
vec2 uv = vec2(coords.x / scene_size.x, 1.0 - coords.y / scene_size.y);
vec2 rand_disk = disk_vec(vec2(rand(seed), rand(seed)));
vec2 jittered_uvs = uv + vec2(rand(seed), rand(seed)) / scene_size;
vec2 lens_disk = vec2(0.0);
- if (regs.globals.enable_dof == 1) {
- lens_disk = rand_disk * regs.globals.cam.lens_radius;
+ if (regs.enable_dof == 1) {
+ lens_disk = rand_disk * regs.cam.lens_radius;
}
- vec3 offset = lens_disk.x * regs.globals.cam.right.xyz + lens_disk.y * regs.globals.cam.up.xyz;
- vec3 proj_plane_pos = regs.globals.cam.first_pixel.xyz + jittered_uvs.x * regs.globals.cam.horizontal.xyz + jittered_uvs.y * regs.globals.cam.vertical.xyz;
+ vec3 offset = lens_disk.x * regs.cam.right.xyz + lens_disk.y * regs.cam.up.xyz;
+ vec3 proj_plane_pos = regs.cam.first_pixel.xyz + jittered_uvs.x * regs.cam.horizontal.xyz + jittered_uvs.y * regs.cam.vertical.xyz;
- return ray(regs.globals.cam.position.xyz + offset, proj_plane_pos.xyz - regs.globals.cam.position.xyz - offset, 0.001f, 1e15);
+ return ray(regs.cam.position.xyz + offset, proj_plane_pos.xyz - regs.cam.position.xyz - offset, 0.001f, 1e15);
}
void main() {
- if (any(greaterThanEqual(gl_GlobalInvocationID.xy, uvec2(regs.globals.width, regs.globals.height))))
+ if (any(greaterThanEqual(gl_GlobalInvocationID.xy, uvec2(regs.width, regs.height))))
return;
- ivec2 coords = ivec2(gl_GlobalInvocationID.xy) * regs.globals.downscale_factor;
+ ivec2 coords = ivec2(gl_GlobalInvocationID.xy) * regs.downscale_factor;
- uint seed = uint(coords.x * uint(1973) + coords.y * uint(9277) + regs.globals.sample_index * uint(26699)) | uint(1);
+ uint seed = uint(coords.x * uint(1973) + coords.y * uint(9277) + regs.sample_index * uint(26699)) | uint(1);
ray r = generate_camera_ray(coords, seed);
vec3 out_color = vec3(0.0);
- if (regs.globals.debug_bvh == 1) {
+ if (regs.debug_bvh == 1) {
out_color = hit_aabbs(r) * vec3(0.001, 0.0, 0.0);
} else {
out_color = ray_color(r, seed);
}
// TODO: what is going on with srgb here ?
- float spp_scale = (1.0 / regs.globals.sample_index);
- vec3 acc_color = srgb_to_linear(imageLoad(images[nonuniformEXT(regs.draw.accumulation_image_index)], coords).xyz);
+ float spp_scale = (1.0 / regs.sample_index);
+ vec3 acc_color = srgb_to_linear(imageLoad(images[nonuniformEXT(regs.accumulation_image_index)], coords).xyz);
out_color = linear_to_srgb(mix(acc_color, out_color, spp_scale));
- imageStore(images[nonuniformEXT(regs.draw.output_image_index)], coords, vec4(out_color, 1.0));
+ imageStore(images[nonuniformEXT(regs.output_image_index)], coords, vec4(out_color, 1.0));
}
diff --git a/shaders/include/ray.h b/shaders/include/ray.h
index 2e9980b..7a6cc21 100644
--- a/shaders/include/ray.h
+++ b/shaders/include/ray.h
@@ -18,38 +18,38 @@ struct hit_info {
};
uvec4 decode_triangle_indices(uint triangle_id) {
- uint id1 = regs.draw.indices_arr.indices[triangle_id * 3] & 0x00ffffff;
- uint id2 = regs.draw.indices_arr.indices[triangle_id * 3 + 1] & 0x00ffffff;
- uint id3 = regs.draw.indices_arr.indices[triangle_id * 3 + 2] & 0x00ffffff;
+ uint id1 = regs.indices_arr.indices[triangle_id * 3] & 0x00ffffff;
+ uint id2 = regs.indices_arr.indices[triangle_id * 3 + 1] & 0x00ffffff;
+ uint id3 = regs.indices_arr.indices[triangle_id * 3 + 2] & 0x00ffffff;
- uint mat_id = (regs.draw.indices_arr.indices[triangle_id * 3] & 0xff000000) >> 8
- | (regs.draw.indices_arr.indices[triangle_id * 3 + 1] & 0xff000000) >> 16
- | (regs.draw.indices_arr.indices[triangle_id * 3 + 2] & 0xff000000) >> 24;
+ uint mat_id = (regs.indices_arr.indices[triangle_id * 3] & 0xff000000) >> 8
+ | (regs.indices_arr.indices[triangle_id * 3 + 1] & 0xff000000) >> 16
+ | (regs.indices_arr.indices[triangle_id * 3 + 2] & 0xff000000) >> 24;
return uvec4(id1, id2, id3, mat_id);
}
vec3[3] get_triangle_positions(uvec3 indices) {
return vec3[3](
- vec3(regs.draw.positions_arr.positions[indices[0] * 3], regs.draw.positions_arr.positions[indices[0] * 3 + 1], regs.draw.positions_arr.positions[indices[0] * 3 + 2]),
- vec3(regs.draw.positions_arr.positions[indices[1] * 3], regs.draw.positions_arr.positions[indices[1] * 3 + 1], regs.draw.positions_arr.positions[indices[1] * 3 + 2]),
- vec3(regs.draw.positions_arr.positions[indices[2] * 3], regs.draw.positions_arr.positions[indices[2] * 3 + 1], regs.draw.positions_arr.positions[indices[2] * 3 + 2])
+ vec3(regs.positions_arr.positions[indices[0] * 3], regs.positions_arr.positions[indices[0] * 3 + 1], regs.positions_arr.positions[indices[0] * 3 + 2]),
+ vec3(regs.positions_arr.positions[indices[1] * 3], regs.positions_arr.positions[indices[1] * 3 + 1], regs.positions_arr.positions[indices[1] * 3 + 2]),
+ vec3(regs.positions_arr.positions[indices[2] * 3], regs.positions_arr.positions[indices[2] * 3 + 1], regs.positions_arr.positions[indices[2] * 3 + 2])
);
}
vec3[3] get_triangle_normals(uvec3 indices) {
return vec3[3](
- vec3(regs.draw.normals_arr.normals[indices[0] * 3], regs.draw.normals_arr.normals[indices[0] * 3 + 1], regs.draw.normals_arr.normals[indices[0] * 3 + 2]),
- vec3(regs.draw.normals_arr.normals[indices[1] * 3], regs.draw.normals_arr.normals[indices[1] * 3 + 1], regs.draw.normals_arr.normals[indices[1] * 3 + 2]),
- vec3(regs.draw.normals_arr.normals[indices[2] * 3], regs.draw.normals_arr.normals[indices[2] * 3 + 1], regs.draw.normals_arr.normals[indices[2] * 3 + 2])
+ vec3(regs.normals_arr.normals[indices[0] * 3], regs.normals_arr.normals[indices[0] * 3 + 1], regs.normals_arr.normals[indices[0] * 3 + 2]),
+ vec3(regs.normals_arr.normals[indices[1] * 3], regs.normals_arr.normals[indices[1] * 3 + 1], regs.normals_arr.normals[indices[1] * 3 + 2]),
+ vec3(regs.normals_arr.normals[indices[2] * 3], regs.normals_arr.normals[indices[2] * 3 + 1], regs.normals_arr.normals[indices[2] * 3 + 2])
);
}
vec2[3] get_triangle_uvs(uvec3 indices) {
return vec2[3](
- vec2(regs.draw.uvs_arr.uvs[indices[0] * 2], regs.draw.uvs_arr.uvs[indices[0] * 2 + 1]),
- vec2(regs.draw.uvs_arr.uvs[indices[1] * 2], regs.draw.uvs_arr.uvs[indices[1] * 2 + 1]),
- vec2(regs.draw.uvs_arr.uvs[indices[2] * 2], regs.draw.uvs_arr.uvs[indices[2] * 2 + 1])
+ vec2(regs.uvs_arr.uvs[indices[0] * 2], regs.uvs_arr.uvs[indices[0] * 2 + 1]),
+ vec2(regs.uvs_arr.uvs[indices[1] * 2], regs.uvs_arr.uvs[indices[1] * 2 + 1]),
+ vec2(regs.uvs_arr.uvs[indices[2] * 2], regs.uvs_arr.uvs[indices[2] * 2 + 1])
);
}
@@ -59,7 +59,7 @@ triangle get_triangle(uint triangle_id) {
get_triangle_positions(indices.xyz),
get_triangle_normals(indices.xyz),
get_triangle_uvs(indices.xyz),
- regs.draw.materials_arr.materials[indices.w]
+ regs.materials_arr.materials[indices.w]
);
}
@@ -82,20 +82,20 @@ uint hit_aabbs(ray r) {
int id = 0;
while(id != -1) {
- if (regs.draw.bvh.nodes[id].primitive_id != -1) {
- // triangle tri = bufs.geometry.triangles[regs.draw.bvh.nodes[id].primitive_id];
+ if (regs.bvh.nodes[id].primitive_id != -1) {
+ // triangle tri = bufs.geometry.triangles[regs.bvh.nodes[id].primitive_id];
// vec3 minimum = min(tri.v1.position, min(tri.v2.position, tri.v3.position)).xyz;
// vec3 maximum = max(tri.v1.position, max(tri.v2.position, tri.v3.position)).xyz;
// if (hit_aabb(minimum, maximum, r)) {
// hit_count++;
// }
- id = regs.draw.bvh.nodes[id].next_id;
- } else if (hit_aabb(regs.draw.bvh.nodes[id].min, regs.draw.bvh.nodes[id].max, r)) {
+ id = regs.bvh.nodes[id].next_id;
+ } else if (hit_aabb(regs.bvh.nodes[id].min, regs.bvh.nodes[id].max, r)) {
hit_count++;
id++;
} else {
- id = regs.draw.bvh.nodes[id].next_id;
+ id = regs.bvh.nodes[id].next_id;
}
}
@@ -169,22 +169,22 @@ bool hit_node(ray r, out hit_info info) {
while(id != -1) {
// Leafs
- if (regs.draw.bvh.nodes[id].primitive_id != -1) {
- // if (hit_sphere(bufs.geometry.spheres[regs.draw.bvh.nodes[id].primitive_id], r, temp_info)) {
+ if (regs.bvh.nodes[id].primitive_id != -1) {
+ // if (hit_sphere(bufs.geometry.spheres[regs.bvh.nodes[id].primitive_id], r, temp_info)) {
// info = temp_info;
// r.max_t = temp_info.t;
// hit = true;
// }
- if (hit_triangle(regs.draw.bvh.nodes[id].primitive_id, r, temp_info)) {
+ if (hit_triangle(regs.bvh.nodes[id].primitive_id, r, temp_info)) {
info = temp_info;
r.max_t = temp_info.t;
hit = true;
}
- id = regs.draw.bvh.nodes[id].next_id;
- } else if (hit_aabb(regs.draw.bvh.nodes[id].min, regs.draw.bvh.nodes[id].max, r)) {
+ id = regs.bvh.nodes[id].next_id;
+ } else if (hit_aabb(regs.bvh.nodes[id].min, regs.bvh.nodes[id].max, r)) {
id++;
} else {
- id = regs.draw.bvh.nodes[id].next_id;
+ id = regs.bvh.nodes[id].next_id;
}
}
diff --git a/shaders/test.comp b/shaders/test.comp
index 3a4230f..b2ddf1c 100644
--- a/shaders/test.comp
+++ b/shaders/test.comp
@@ -1,29 +1,27 @@
#extension GL_EXT_buffer_reference : require
#extension GL_EXT_nonuniform_qualifier : require
+#extension GL_EXT_descriptor_heap : require
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
-layout(set = 0, binding = 0) uniform sampler samplers[];
-layout(set = 0, binding = 1) uniform texture2D textures[];
-layout(set = 0, binding = 2, rgba32f) uniform image2D images[];
+layout(descriptor_heap) uniform texture2D textures[];
+layout(descriptor_heap, rgba32f) uniform image2D images[];
+layout(descriptor_heap) uniform sampler samplers[];
-layout(buffer_reference) readonly buffer draw_params {
+
+layout(push_constant) uniform buffers {
uint input_id1;
uint input_id2;
uint output_id;
uint pad;
-};
-
-layout(push_constant) uniform buffers {
- layout(offset = 16) draw_params draw;
} regs;
void main() {
ivec2 coords = ivec2(gl_GlobalInvocationID.xy);
float t = 0.5;
- vec3 color_1 = imageLoad(images[nonuniformEXT(regs.draw.input_id1)], coords).xyz;
- vec3 color_2 = imageLoad(images[nonuniformEXT(regs.draw.input_id2)], coords).xyz;
+ vec3 color_1 = imageLoad(images[nonuniformEXT(regs.input_id1)], coords).xyz;
+ vec3 color_2 = imageLoad(images[nonuniformEXT(regs.input_id2)], coords).xyz;
vec3 out_color = (t * color_1) + ((1.0 - t) * color_2);
- imageStore(images[nonuniformEXT(regs.draw.output_id)], coords, vec4(out_color, 1.0));
+ imageStore(images[nonuniformEXT(regs.output_id)], coords, vec4(out_color, 1.0));
}
diff --git a/shaders/tonemapping.comp b/shaders/tonemapping.comp
index 65251df..ed30c92 100644
--- a/shaders/tonemapping.comp
+++ b/shaders/tonemapping.comp
@@ -1,9 +1,10 @@
#extension GL_EXT_buffer_reference : require
#extension GL_EXT_nonuniform_qualifier : require
+#extension GL_EXT_descriptor_heap : require
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
-layout(set = 0, binding = 2, rgba32f) uniform image2D images[];
+layout(descriptor_heap, rgba32f) uniform image2D images[];
struct camera {
vec4 position;
@@ -22,44 +23,21 @@ struct camera {
float aspect_ratio;
};
-layout(buffer_reference) readonly buffer global_params {
- camera cam;
-
- uint max_bounce;
- uint min_bounce;
- uint width;
- uint height;
-
- uint sample_index;
- uint enable_dof;
- uint debug_bvh;
+layout(push_constant) uniform registers {
int downscale_factor;
-};
-
-layout(buffer_reference) readonly buffer pass_params {
- uint padding;
-};
-
-layout(buffer_reference) readonly buffer draw_params {
uint output_image_index;
uint accumulation_image_index;
-};
-
-layout(push_constant) uniform registers {
- global_params globals;
- pass_params pass;
- draw_params draw;
} regs;
void main() {
- ivec2 coords = ivec2(gl_GlobalInvocationID.xy) * regs.globals.downscale_factor;
+ ivec2 coords = ivec2(gl_GlobalInvocationID.xy) * regs.downscale_factor;
- vec3 color = imageLoad(images[nonuniformEXT(regs.draw.accumulation_image_index)], coords).rgb;
+ vec3 color = imageLoad(images[nonuniformEXT(regs.accumulation_image_index)], coords).rgb;
vec3 out_color = sqrt(color);
- for (uint i = 0; i < regs.globals.downscale_factor; i++) {
- for (uint j = 0; j < regs.globals.downscale_factor; j++) {
- imageStore(images[nonuniformEXT(regs.draw.output_image_index)], coords + ivec2(i, j), vec4(out_color, 1.0));
+ for (uint i = 0; i < regs.downscale_factor; i++) {
+ for (uint j = 0; j < regs.downscale_factor; j++) {
+ imageStore(images[nonuniformEXT(regs.output_image_index)], coords + ivec2(i, j), vec4(out_color, 1.0));
}
}
}
diff --git a/shaders/transmittance_lut.comp b/shaders/transmittance_lut.comp
index aadc55a..f932d69 100644
--- a/shaders/transmittance_lut.comp
+++ b/shaders/transmittance_lut.comp
@@ -1,11 +1,12 @@
#extension GL_EXT_buffer_reference : require
#extension GL_EXT_nonuniform_qualifier : require
+#extension GL_EXT_descriptor_heap : require
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
-layout(set = 0, binding = 0) uniform sampler samplers[];
-layout(set = 0, binding = 1) uniform texture2D textures[];
-layout(set = 0, binding = 2, rgba32f) uniform image2D images[];
+layout(descriptor_heap) uniform texture2D textures[];
+layout(descriptor_heap, rgba32f) uniform image2D images[];
+layout(descriptor_heap) uniform sampler samplers[];
layout(buffer_reference) readonly buffer draw_params {
uint output_image_index;
diff --git a/src/main.cpp b/src/main.cpp
index 3cb56dc..a046c0a 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -48,7 +48,6 @@
#include "vulkan-loader.cpp"
#include "vk-utils.cpp"
#include "vk-device.cpp"
-#include "vk-bindless.cpp"
#include "vk-command-buffer.cpp"
#endif
@@ -190,15 +189,15 @@ int main() {
const float focus_distance = 10.f;
#if VK
- auto& device = vkdevice::get();
+ auto& render_device = vkdevice::get();
#else
- auto& device = dx12::device::get();
+ auto& render_device = dx12::device::get();
#endif
- device.init();
+ render_device.init();
scene main_scene = scene(camera(position, target, v_fov, aspect_ratio, aperture, focus_distance), window_width, window_height);
- handle<device_surface> surface_handle = device.create_surface({
+ handle<device_surface> surface_handle = render_device.create_surface({
.window_handle = wnd.handle,
#if VK
.surface_format = {
@@ -214,13 +213,13 @@ int main() {
#endif
.image_count = 2U,
});
- const device_surface* surface = device.get_surface(surface_handle);
+ const device_surface* surface = render_device.get_surface(surface_handle);
// ==============
// create buffers
// ==============
- const handle<device_buffer> staging_buffer_handle = device.create_buffer({
+ const handle<device_buffer> staging_buffer_handle = render_device.create_buffer({
.size = 128 * MB,
#if VK
.usages = VK_BUFFER_USAGE_2_TRANSFER_SRC_BIT,
@@ -233,9 +232,9 @@ int main() {
.heap_type = D3D12_HEAP_TYPE_UPLOAD,
#endif
});
- const device_buffer* staging_buffer = device.get_buffer(staging_buffer_handle);
+ const device_buffer* staging_buffer = render_device.get_buffer(staging_buffer_handle);
- const handle<device_buffer> vertex_buffer_handle = device.create_buffer({
+ const handle<device_buffer> vertex_buffer_handle = render_device.create_buffer({
.size = MB * sizeof(uint32_t),
#if VK
.usages = VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT,
@@ -245,7 +244,7 @@ int main() {
#endif
});
- const handle<device_buffer> index_buffer_handle = device.create_buffer({
+ const handle<device_buffer> index_buffer_handle = render_device.create_buffer({
.size = MB * sizeof(uint32_t),
#if VK
.usages = VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_2_INDEX_BUFFER_BIT,
@@ -255,8 +254,8 @@ int main() {
#endif
});
- device_buffer* vertex_buffer = device.get_buffer(vertex_buffer_handle);
- device_buffer* index_buffer = device.get_buffer(index_buffer_handle);
+ device_buffer* vertex_buffer = render_device.get_buffer(vertex_buffer_handle);
+ device_buffer* index_buffer = render_device.get_buffer(index_buffer_handle);
// ================
@@ -265,20 +264,20 @@ int main() {
#if VK
size_t code_size = 0U;
uint8_t* code = read_file("shaders/test.comp.spv", &code_size);
- handle<device_pipeline> compute = device.create_compute_pipeline({
+ handle<device_pipeline> compute = render_device.create_compute_pipeline({
.cs_code = code,
.cs_code_size = code_size,
});
size_t rt_code_size = 0U;
uint8_t* rt_code = read_file("shaders/compute.comp.spv", &rt_code_size);
- handle<device_pipeline> raytracing = device.create_compute_pipeline({
+ handle<device_pipeline> raytracing = render_device.create_compute_pipeline({
.cs_code = rt_code,
.cs_code_size = rt_code_size,
});
size_t tonemapping_code_size = 0U;
uint8_t* tonemapping_code = read_file("shaders/tonemapping.comp.spv", &tonemapping_code_size);
- handle<device_pipeline> tonemapping = device.create_compute_pipeline({
+ handle<device_pipeline> tonemapping = render_device.create_compute_pipeline({
.cs_code = tonemapping_code,
.cs_code_size = tonemapping_code_size,
});
@@ -288,7 +287,7 @@ int main() {
uint8_t* vertex_code = read_file("shaders/api-test-ui.vert.spv", &vertex_code_size);
size_t fragment_code_size = 0U;
uint8_t* fragment_code = read_file("shaders/api-test-ui.frag.spv", &fragment_code_size);
- handle<device_pipeline> graphics = device.create_graphics_pipeline({
+ handle<device_pipeline> graphics = render_device.create_graphics_pipeline({
.vs_code = vertex_code,
.vs_code_size = vertex_code_size,
.fs_code = fragment_code,
@@ -299,7 +298,7 @@ int main() {
size_t transmittance_lut_code_size = 0U;
u8* transmittance_lut_code = read_file("shaders/transmittance_lut.comp.spv", &transmittance_lut_code_size);
- handle<device_pipeline> transmittance_lut_compute = device.create_compute_pipeline({
+ handle<device_pipeline> transmittance_lut_compute = render_device.create_compute_pipeline({
.cs_code = transmittance_lut_code,
.cs_code_size = transmittance_lut_code_size,
.name = "transmittance_lut_comp",
@@ -336,7 +335,7 @@ int main() {
// ==============
// create texures
// ==============
- const handle<device_texture> gpu_texture_handle = device.create_texture({
+ const handle<device_texture> gpu_texture_handle = render_device.create_texture({
.width = static_cast<uint32_t>(image_width),
.height = static_cast<uint32_t>(image_height),
#if VK
@@ -351,7 +350,7 @@ int main() {
#endif
});
- const handle<device_texture> second_texture = device.create_texture({
+ const handle<device_texture> second_texture = render_device.create_texture({
.width = static_cast<uint32_t>(image_width),
.height = static_cast<uint32_t>(image_height),
#if VK
@@ -366,7 +365,7 @@ int main() {
#endif
});
- const handle<device_texture> output_texture_handle = device.create_texture({
+ const handle<device_texture> output_texture_handle = render_device.create_texture({
.width = static_cast<uint32_t>(image_width),
.height = static_cast<uint32_t>(image_height),
#if VK
@@ -380,7 +379,7 @@ int main() {
#endif
});
- const handle<device_texture> ui_texture_handle = device.create_texture({
+ const handle<device_texture> ui_texture_handle = render_device.create_texture({
.width = static_cast<uint32_t>(atlas_width),
.height = static_cast<uint32_t>(atlas_height),
#if VK
@@ -396,7 +395,7 @@ int main() {
.name = "glyph atlas"
});
- const handle<device_texture> acc_handle = device.create_texture({
+ const handle<device_texture> acc_handle = render_device.create_texture({
.width = static_cast<uint32_t>(window_width),
.height = static_cast<uint32_t>(window_height),
#if VK
@@ -412,7 +411,7 @@ int main() {
.name = "accumulation texture"
});
- const handle<device_texture> result_handle = device.create_texture({
+ const handle<device_texture> result_handle = render_device.create_texture({
.width = static_cast<uint32_t>(window_width),
.height = static_cast<uint32_t>(window_height),
#if VK
@@ -428,7 +427,7 @@ int main() {
.name = "output texture"
});
- const handle<device_texture> transmittance_lut_handle = device.create_texture({
+ const handle<device_texture> transmittance_lut_handle = render_device.create_texture({
.width = static_cast<uint32_t>(1024),
.height = static_cast<uint32_t>(1024),
#if VK
@@ -444,12 +443,12 @@ int main() {
});
#if VK
- u32 acc_storage_index = device.get_texture(acc_handle)->get_storage_index();
- u32 result_storage_index = device.get_texture(result_handle)->get_storage_index();
+ u32 acc_storage_index = render_device.get_texture(acc_handle)->get_storage_index();
+ u32 result_storage_index = render_device.get_texture(result_handle)->get_storage_index();
#endif
- const device_texture* ui_texture = device.get_texture(ui_texture_handle);
- const device_texture* transmittance_lut = device.get_texture(transmittance_lut_handle);
+ const device_texture* ui_texture = render_device.get_texture(ui_texture_handle);
+ const device_texture* transmittance_lut = render_device.get_texture(transmittance_lut_handle);
debug_texture_list.push_back(transmittance_lut_handle);
io.Fonts->SetTexID(reinterpret_cast<void*>(static_cast<uintptr_t>(ui_texture->get_sampled_index())));
@@ -457,10 +456,10 @@ int main() {
#if VK
std::array<graphics_command_buffer, 4U> graphics_command_buffers;
- device.allocate_command_buffers(graphics_command_buffers.data(), graphics_command_buffers.size(), QueueType::GRAPHICS, "graphics_cmd_buf");
+ render_device.allocate_command_buffers(graphics_command_buffers.data(), graphics_command_buffers.size(), QueueType::GRAPHICS, "graphics_cmd_buf");
#else
std::array<dx12::graphics_command_buffer, 4U> graphics_command_buffers;
- device.allocate_command_buffers(graphics_command_buffers.data(), graphics_command_buffers.size(), dx12::QueueType::GRAPHICS);
+ render_device.allocate_command_buffers(graphics_command_buffers.data(), graphics_command_buffers.size(), dx12::QueueType::GRAPHICS);
#endif
@@ -485,21 +484,17 @@ int main() {
{
- // device_buffer* draws_uniform_buffer = device.get_bindingmodel().get_uniform_buffer(UniformTypes::DRAW);
{
struct params {
u32 input1;
u32 input2;
u32 output;
u32 pad;
- // } *params = draws_uniform_buffer->allocate<struct params>();
- } params;
- // params->input1 = device.get_texture(second_texture)->get_storage_index();
- // params->input2 = device.get_texture(gpu_texture_handle)->get_storage_index();
- // params->output = device.get_texture(output_texture_handle)->get_storage_index();
- params.input1 = device.get_texture(second_texture)->get_storage_index();
- params.input2 = device.get_texture(gpu_texture_handle)->get_storage_index();
- params.output = device.get_texture(output_texture_handle)->get_storage_index();
+ } params = {
+ .input1 = render_device.get_texture(second_texture)->get_storage_index(),
+ .input2 = render_device.get_texture(gpu_texture_handle)->get_storage_index(),
+ .output = render_device.get_texture(output_texture_handle)->get_storage_index(),
+ };
graphics_command_buffers[0].dispatch({
.pipeline = compute,
@@ -515,14 +510,11 @@ int main() {
u32 width;
u32 height;
u32 pad;
- // } *params = draws_uniform_buffer->allocate<struct params>();
- } params;
- // params->lut_id = transmittance_lut->get_storage_index();
- // params->width = transmittance_lut->width;
- // params->height = transmittance_lut->height;
- params.lut_id = transmittance_lut->get_storage_index();
- params.width = transmittance_lut->width;
- params.height = transmittance_lut->height;
+ } params = {
+ .lut_id = transmittance_lut->get_storage_index(),
+ .width = transmittance_lut->width,
+ .height = transmittance_lut->height,
+ };
graphics_command_buffers[0].dispatch({
.pipeline = transmittance_lut_compute,
@@ -538,8 +530,8 @@ int main() {
graphics_command_buffers[0].stop();
- device.submit(graphics_command_buffers.data(), 1);
- device.wait();
+ render_device.submit(graphics_command_buffers.data(), 1);
+ render_device.wait();
RD_END_CAPTURE;
@@ -665,16 +657,8 @@ int main() {
}
}
- // ======================
- // global uniforms update
- // ======================
- {
- // metadata* const globals = vkdevice::get().get_bindingmodel().get_uniform_buffer(UniformTypes::GLOBAL)->allocate<metadata>();
- // memcpy(static_cast<void*>(globals), &main_scene.meta, sizeof(main_scene.meta));
- }
-
// TODO: Refactor backbuffer acquisition
- auto backbuffer = surface->swapchain_images[device.acquire_image_index(surface_handle)];
+ auto backbuffer = surface->swapchain_images[render_device.acquire_image_index(surface_handle)];
color_attachment[0] = backbuffer;
// RD_START_CAPTURE;
@@ -692,7 +676,9 @@ int main() {
}
{
+ // TODO: Pack this fields
struct params {
+ struct metadata meta;
uintptr_t bvh_buffer;
uintptr_t indices_buffer;
uintptr_t positions_buffer;
@@ -701,25 +687,17 @@ int main() {
uintptr_t materials_buffer;
u32 output_id;
u32 accumulation_id;
+ } uniforms = {
+ .meta = main_scene.meta,
+ .bvh_buffer = main_scene.bvh_buffer_address(),
+ .indices_buffer = main_scene.indices_buffer_address(),
+ .positions_buffer = main_scene.positions_buffer_address(),
+ .normals_buffer = main_scene.normals_buffer_address(),
+ .uvs_buffer = main_scene.uvs_buffer_address(),
+ .materials_buffer = main_scene.materials_buffer_address(),
+ .output_id = (virtual_frame_index == 0U) ? result_storage_index : acc_storage_index,
+ .accumulation_id = (virtual_frame_index == 0U) ? acc_storage_index : result_storage_index,
};
- // struct params* uniforms = device.get_bindingmodel().get_uniform_buffer(UniformTypes::DRAW)->allocate<params>();
- // uniforms->bvh_buffer = main_scene.bvh_buffer_address();
- // uniforms->indices_buffer = main_scene.indices_buffer_address();
- // uniforms->positions_buffer = main_scene.positions_buffer_address();
- // uniforms->normals_buffer = main_scene.normals_buffer_address();
- // uniforms->uvs_buffer = main_scene.uvs_buffer_address();
- // uniforms->materials_buffer = main_scene.materials_buffer_address();
- // uniforms->output_id = (virtual_frame_index == 0U) ? result_storage_index : acc_storage_index;
- // uniforms->accumulation_id = (virtual_frame_index == 0U) ? acc_storage_index : result_storage_index;
- struct params uniforms = {};
- uniforms.bvh_buffer = main_scene.bvh_buffer_address();
- uniforms.indices_buffer = main_scene.indices_buffer_address();
- uniforms.positions_buffer = main_scene.positions_buffer_address();
- uniforms.normals_buffer = main_scene.normals_buffer_address();
- uniforms.uvs_buffer = main_scene.uvs_buffer_address();
- uniforms.materials_buffer = main_scene.materials_buffer_address();
- uniforms.output_id = (virtual_frame_index == 0U) ? result_storage_index : acc_storage_index;
- uniforms.accumulation_id = (virtual_frame_index == 0U) ? acc_storage_index : result_storage_index;
command_buffer.dispatch({
.pipeline = raytracing,
@@ -730,15 +708,15 @@ int main() {
{
struct params {
+ s32 downscale_factor;
u32 output_id;
u32 accumulation_id;
- // } *uniforms = device.get_bindingmodel().get_uniform_buffer(UniformTypes::DRAW)->allocate<params>();
- } uniforms;
- // TODO: Refactor backbuffer acquisition
- // uniforms->output_id = device.get_texture(backbuffer)->get_storage_index();
- // uniforms->accumulation_id = (virtual_frame_index == 0U) ? result_storage_index : acc_storage_index;
- uniforms.output_id = device.get_texture(backbuffer)->get_storage_index();
- uniforms.accumulation_id = (virtual_frame_index == 0U) ? result_storage_index : acc_storage_index;
+ } uniforms = {
+ // TODO: Refactor backbuffer acquisition
+ .downscale_factor = main_scene.meta.downscale_factor,
+ .output_id = render_device.get_texture(backbuffer)->get_storage_index(),
+ .accumulation_id = (virtual_frame_index == 0U) ? result_storage_index : acc_storage_index,
+ };
command_buffer.dispatch({
.pipeline = tonemapping,
@@ -761,7 +739,6 @@ int main() {
.color_attachments_count = color_attachment.size(),
});
- // device_buffer* draws_uniform_buffer = device.get_bindingmodel().get_uniform_buffer(UniformTypes::DRAW);
uint32_t vertex_offset = 0;
uint32_t index_offset = 0;
for (s32 index = 0U ; index < draw_data->CmdListsCount; index++) {
@@ -775,10 +752,7 @@ int main() {
float translate[2U];
uint32_t texture_index;
u32 padding;
- };
- // struct ui_params* ui_param = draws_uniform_buffer->allocate<ui_params>();
- // *ui_param = ui_params{
- struct ui_params ui_param = ui_params{
+ } ui_param = {
.vertex_buffer = vertex_buffer->device_address,
.scale {
2.f / draw_data->DisplaySize.x,
@@ -809,9 +783,8 @@ int main() {
command_buffer.stop();
- device.submit_before_present(surface_handle, &command_buffer, 1U);
- device.present(surface_handle);
- // device.wait();
+ render_device.submit_before_present(surface_handle, &command_buffer, 1U);
+ render_device.present(surface_handle);
LARGE_INTEGER end_qpc;
QueryPerformanceCounter(&end_qpc);
@@ -822,31 +795,31 @@ int main() {
// RD_END_CAPTURE;
}
- device.wait();
+ render_device.wait();
main_scene.deinit();
- device.destroy_surface(surface_handle);
+ render_device.destroy_surface(surface_handle);
- device.destroy_pipeline(compute);
- device.destroy_pipeline(graphics);
- device.destroy_pipeline(raytracing);
- device.destroy_pipeline(tonemapping);
+ render_device.destroy_pipeline(compute);
+ render_device.destroy_pipeline(graphics);
+ render_device.destroy_pipeline(raytracing);
+ render_device.destroy_pipeline(tonemapping);
- device.destroy_pipeline(transmittance_lut_compute);
- device.destroy_texture(transmittance_lut_handle);
+ render_device.destroy_pipeline(transmittance_lut_compute);
+ render_device.destroy_texture(transmittance_lut_handle);
- device.destroy_texture(gpu_texture_handle);
- device.destroy_texture(second_texture);
- device.destroy_texture(output_texture_handle);
- device.destroy_texture(ui_texture_handle);
- device.destroy_texture(acc_handle);
- device.destroy_texture(result_handle);
+ render_device.destroy_texture(gpu_texture_handle);
+ render_device.destroy_texture(second_texture);
+ render_device.destroy_texture(output_texture_handle);
+ render_device.destroy_texture(ui_texture_handle);
+ render_device.destroy_texture(acc_handle);
+ render_device.destroy_texture(result_handle);
- device.destroy_buffer(staging_buffer_handle);
- device.destroy_buffer(vertex_buffer_handle);
- device.destroy_buffer(index_buffer_handle);
- device.deinit();
+ render_device.destroy_buffer(staging_buffer_handle);
+ render_device.destroy_buffer(vertex_buffer_handle);
+ render_device.destroy_buffer(index_buffer_handle);
+ render_device.deinit();
ImGui::DestroyContext();
#endif // VK
diff --git a/src/scene.cpp b/src/scene.cpp
index d8533f9..ae009e7 100644
--- a/src/scene.cpp
+++ b/src/scene.cpp
@@ -55,15 +55,12 @@ metadata::metadata(const camera &cam, uint32_t width, uint32_t height)
: cam(cam), width(width), height(height) {}
scene::scene(const camera& cam, uint32_t width, uint32_t height)
- :model("../models/sponza/Sponza.gltf"), meta(cam, width, height) {
+ // :model("../models/sponza/Sponza.gltf"), meta(cam, width, height) {
// :model("../models/BistroInterior/BistroInterior.gltf"), meta(cam, width, height) {
// :model("../models/BistroExterior/BistroExterior.gltf"), meta(cam, width, height) {
- // :model("../models/sponza-avif-hi.glb"), meta(cam, width, height) {
// :model("../models/main_sponza/NewSponza_Main_glTF_003.gltf"), meta(cam, width, height) {
// :model("../models/pkg_a_curtains/NewSponza_Curtains_glTF.gltf"), meta(cam, width, height) {
- // :model("../models/sponza.glb", true), meta(cam, width, height) {
-
- auto& device = vkdevice::get();
+ :model("../models/sponza.glb", true), meta(cam, width, height) {
// Geometry & BVH
std::vector<uint32_t> indices;
@@ -151,12 +148,12 @@ scene::scene(const camera& cam, uint32_t width, uint32_t height)
});
if (material.base_color_texture.id != handle<device_texture>::invalid_id) {
- mat.albedo_texture_id = device.get_texture(material.base_color_texture).get_sampled_index();
+ mat.albedo_texture_id = vkdevice::get().get_texture(material.base_color_texture)->get_sampled_index();
// mat.albedo_texture_sampler_id = device.get_sampler(0);
}
if (material.metallic_roughness_texture.id != handle<device_texture>::invalid_id) {
- mat.metallic_roughness_texture_id = device.get_texture(material.metallic_roughness_texture).get_sampled_index();
+ mat.metallic_roughness_texture_id = vkdevice::get().get_texture(material.metallic_roughness_texture)->get_sampled_index();
// mat.metallic_roughness_texture_sampler_id = device.get_sampler(0);
}
}
@@ -179,80 +176,80 @@ scene::scene(const camera& cam, uint32_t width, uint32_t height)
// bvh builder(spheres, packed_nodes);
{
- indices_buffer_handle = device.create_buffer({
+ indices_buffer_handle = vkdevice::get().create_buffer({
.size = indices.size() * sizeof(indices[0]),
- .usages = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
+ .usages = VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT,
.memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
.memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
.name = "indices",
});
- const auto& indices_buffer = device.get_buffer(indices_buffer_handle);
- void* ptr = indices_buffer.mapped_ptr;
+ const auto& indices_buffer = vkdevice::get().get_buffer(indices_buffer_handle);
+ void* ptr = indices_buffer->mapped_ptr;
memcpy(ptr, indices.data(), indices.size() * sizeof(indices[0]));
}
{
- positions_buffer_handle = device.create_buffer({
+ positions_buffer_handle = vkdevice::get().create_buffer({
.size = positions.size() * sizeof(positions[0]),
- .usages = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
+ .usages = VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT,
.memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
.memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
.name = "positions",
});
- const auto& positions_buffer = device.get_buffer(positions_buffer_handle);
- void* ptr = positions_buffer.mapped_ptr;
+ const auto& positions_buffer = vkdevice::get().get_buffer(positions_buffer_handle);
+ void* ptr = positions_buffer->mapped_ptr;
memcpy(ptr, positions.data(), positions.size() * sizeof(positions[0]));
}
{
- normals_buffer_handle = device.create_buffer({
+ normals_buffer_handle = vkdevice::get().create_buffer({
.size = normals.size() * sizeof(normals[0]),
- .usages = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
+ .usages = VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT,
.memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
.memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
.name = "normals",
});
- const auto& normals_buffer = device.get_buffer(normals_buffer_handle);
- void* ptr = normals_buffer.mapped_ptr;
+ const auto& normals_buffer = vkdevice::get().get_buffer(normals_buffer_handle);
+ void* ptr = normals_buffer->mapped_ptr;
memcpy(ptr, normals.data(), normals.size() * sizeof(normals[0]));
}
{
- uvs_buffer_handle = device.create_buffer({
+ uvs_buffer_handle = vkdevice::get().create_buffer({
.size = uvs.size() * sizeof(uvs[0]),
- .usages = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
+ .usages = VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT,
.memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
.memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
.name = "uvs",
});
- const auto& uvs_buffer = device.get_buffer(uvs_buffer_handle);
- void* ptr = uvs_buffer.mapped_ptr;
+ const auto& uvs_buffer = vkdevice::get().get_buffer(uvs_buffer_handle);
+ void* ptr = uvs_buffer->mapped_ptr;
memcpy(ptr, uvs.data(), uvs.size() * sizeof(uvs[0]));
}
{
- bvh_buffer_handle = device.create_buffer({
+ bvh_buffer_handle = vkdevice::get().create_buffer({
.size = packed_nodes.size() * sizeof(packed_nodes[0]),
- .usages = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
+ .usages = VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT,
.memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
.memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
.name = "bvh",
});
- const auto& bvh_buffer = device.get_buffer(bvh_buffer_handle);
- void* ptr = bvh_buffer.mapped_ptr;
+ const auto& bvh_buffer = vkdevice::get().get_buffer(bvh_buffer_handle);
+ void* ptr = bvh_buffer->mapped_ptr;
memcpy(ptr, packed_nodes.data(), packed_nodes.size() * sizeof(packed_nodes[0]));
}
{
- materials_buffer_handle = device.create_buffer({
+ materials_buffer_handle = vkdevice::get().create_buffer({
.size = materials.size() * sizeof(materials[0]),
- .usages = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
+ .usages = VK_BUFFER_USAGE_2_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT,
.memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
.memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
.name = "materials",
});
- const auto& materials_buffer = device.get_buffer(materials_buffer_handle);
- void* ptr = materials_buffer.mapped_ptr;
+ const auto& materials_buffer = vkdevice::get().get_buffer(materials_buffer_handle);
+ void* ptr = materials_buffer->mapped_ptr;
memcpy(ptr, materials.data(), materials.size() * sizeof(materials[0]));
}
}
diff --git a/src/vk-bindless.cpp b/src/vk-bindless.cpp
deleted file mode 100644
index 8f29834..0000000
--- a/src/vk-bindless.cpp
+++ /dev/null
@@ -1,238 +0,0 @@
-#include "vk-bindless.hpp"
-
-#include "vk-device.hpp"
-#include "vk-utils.hpp"
-
-device_buffer* bindless_model::get_uniform_buffer(enum UniformTypes type) const {
- return vkdevice::get().get_buffer(uniform_buffers[type]);
-}
-
-void bindless_model::init() {
- vkdevice& render_device = vkdevice::get();
- VkDevice device = render_device.get_device();
-
- // -------------------------
- // create immutable samplers
- // -------------------------
- {
- VkSamplerCreateInfo create_info{
- .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
- .pNext = VK_NULL_HANDLE,
- .flags = 0,
- .mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST,
- .mipLodBias = 0.f,
- .anisotropyEnable = VK_FALSE,
- .compareEnable = VK_FALSE,
- .compareOp = VK_COMPARE_OP_NEVER,
- .minLod = 0.f,
- .maxLod = 0.f,
- .borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,
- .unnormalizedCoordinates = VK_FALSE,
- };
-
- // Nearest sampler
- {
- VkFilter filter = VK_FILTER_NEAREST;
- VkSamplerAddressMode address_mode = VK_SAMPLER_ADDRESS_MODE_REPEAT;
-
- create_info.magFilter = filter,
- create_info.minFilter = filter,
- create_info.addressModeU = address_mode,
- create_info.addressModeV = address_mode,
- create_info.addressModeW = address_mode,
-
- VKCHECK(vkCreateSampler(device, &create_info, VK_NULL_HANDLE, &samplers[SamplerType::NEAREST]));
- }
-
- // Linear sampler
- {
- VkFilter filter = VK_FILTER_LINEAR;
- VkSamplerAddressMode address_mode = VK_SAMPLER_ADDRESS_MODE_REPEAT;
-
- create_info.magFilter = filter,
- create_info.minFilter = filter,
- create_info.addressModeU = address_mode,
- create_info.addressModeV = address_mode,
- create_info.addressModeW = address_mode,
-
- VKCHECK(vkCreateSampler(device, &create_info, VK_NULL_HANDLE, &samplers[SamplerType::LINEAR]));
- }
- }
-
- // Set 0 global resources
- // Binding 0 Storage images
- // Binding 1 Sampled images
- // Binding 2 Samplers
- {
- VkDescriptorSetLayoutBinding set_layout_bindings[]{
- {
- .binding = 0U,
- .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
- .descriptorCount = SamplerType::MAX_SAMPLER,
- .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
- .pImmutableSamplers = samplers,
- },
- {
- .binding = 1U,
- .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
- .descriptorCount = set_descriptors_count,
- .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
- .pImmutableSamplers = nullptr,
- },
- {
- .binding = 2U,
- .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
- .descriptorCount = set_descriptors_count,
- .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT | VK_SHADER_STAGE_FRAGMENT_BIT,
- .pImmutableSamplers = nullptr,
- },
- };
-
- VkDescriptorBindingFlags flags[]{
- VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT,
- VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT,
- VK_DESCRIPTOR_BINDING_PARTIALLY_BOUND_BIT | VK_DESCRIPTOR_BINDING_UPDATE_UNUSED_WHILE_PENDING_BIT,
- };
-
- VkDescriptorSetLayoutBindingFlagsCreateInfo layout_binding_flags{
- .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
- .pNext = VK_NULL_HANDLE,
- .bindingCount = sizeof(flags) / sizeof(VkDescriptorBindingFlags),
- .pBindingFlags = flags,
- };
-
- VkDescriptorSetLayoutCreateInfo create_info{
- .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
- .pNext = &layout_binding_flags,
- .flags = 0U,
- .bindingCount = sizeof(set_layout_bindings) / sizeof(VkDescriptorSetLayoutBinding),
- .pBindings = set_layout_bindings,
- };
-
- VKCHECK(vkCreateDescriptorSetLayout(device, &create_info, nullptr, &global_set_layout));
- }
-
- // ----------------------
- // create layout
- // ----------------------
- {
- VkPushConstantRange push_constant {
- .stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT,
- .offset = 0U,
- .size = push_constant_slot_size * push_constant_slots,
- };
-
- VkPipelineLayoutCreateInfo create_info{
- .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0U,
- .setLayoutCount = 1U,
- .pSetLayouts = &global_set_layout,
- .pushConstantRangeCount = 1U,
- .pPushConstantRanges = &push_constant,
- };
-
- VKCHECK(vkCreatePipelineLayout(device, &create_info, nullptr, &global_layout));
- }
-
- // ----------------------
- // create descriptor pool
- // ----------------------
- {
- VkDescriptorPoolSize pool_sizes[]{
- {
- .type = VK_DESCRIPTOR_TYPE_SAMPLER,
- .descriptorCount = set_descriptors_count,
- },
- {
- .type = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
- .descriptorCount = set_descriptors_count,
- },
- {
- .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
- .descriptorCount = set_descriptors_count,
- },
- };
-
- VkDescriptorPoolCreateInfo descriptor_pool_create_info{
- .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
- .pNext = nullptr,
- .flags = 0U,
- .maxSets = descriptor_pool_allocable_sets_count,
- .poolSizeCount = sizeof(pool_sizes) / sizeof(VkDescriptorPoolSize),
- .pPoolSizes = pool_sizes,
- };
- VKCHECK(vkCreateDescriptorPool(device, &descriptor_pool_create_info, nullptr, &descriptor_pool));
- }
-
- // -----------------------
- // create descriptors sets
- // -----------------------
- {
- VkDescriptorSetAllocateInfo allocate_info{
- .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
- .pNext = nullptr,
- .descriptorPool = descriptor_pool,
- .descriptorSetCount = 1U,
- .pSetLayouts = &global_set_layout,
- };
- VKCHECK(vkAllocateDescriptorSets(device, &allocate_info, &global_set));
- }
-
- // ---------------------
- // global uniform buffer
- // ---------------------
- {
- uniform_buffers[UniformTypes::GLOBAL] = render_device.create_buffer({
- .size = globals_uniform_buffer_size,
- .usages = VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT,
- .memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
- .memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
- .name = "global uniform buffer",
- });
- }
-
- // ---------------------
- // passes uniform buffer
- // ---------------------
- {
- uniform_buffers[UniformTypes::PASS] = render_device.create_buffer({
- .size = passes_uniform_buffer_size,
- .usages = VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT,
- .memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
- .memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
- .name = "passes uniform buffer"
- });
- }
-
- // --------------------
- // draws uniform buffer
- // --------------------
- {
- uniform_buffers[UniformTypes::DRAW] = render_device.create_buffer({
- .size = draws_uniform_buffer_size,
- .usages = VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT,
- .memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
- .memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
- .name = "draws uniform buffer",
- });
- }
-}
-
-void bindless_model::deinit() {
- vkdevice& render_device = vkdevice::get();
- VkDevice device = render_device.get_device();
-
- vkDestroyDescriptorPool(device, descriptor_pool, nullptr);
-
- vkDestroyDescriptorSetLayout(device, global_set_layout, nullptr);
- vkDestroyPipelineLayout(device, global_layout, nullptr);
-
- render_device.destroy_buffer(uniform_buffers[UniformTypes::GLOBAL]);
- render_device.destroy_buffer(uniform_buffers[UniformTypes::PASS]);
- render_device.destroy_buffer(uniform_buffers[UniformTypes::DRAW]);
-
- for (VkSampler sampler : samplers) {
- vkDestroySampler(device, sampler, nullptr);
- }
-}
diff --git a/src/vk-command-buffer.cpp b/src/vk-command-buffer.cpp
index e16e384..00d60a1 100644
--- a/src/vk-command-buffer.cpp
+++ b/src/vk-command-buffer.cpp
@@ -1,7 +1,5 @@
#include "vk-command-buffer.hpp"
-uintptr_t constants[3U] = { 0U };
-
void command_buffer::start() const {
VkCommandBufferBeginInfo begin_info{
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
@@ -12,20 +10,42 @@ void command_buffer::start() const {
VKCHECK(vkBeginCommandBuffer(vk_command_buffer, &begin_info));
- // TODO: Bind heaps
- VkBindHeapInfoEXT image_bind_heap_info = {
- .sType = VK_STRUCTURE_TYPE_BIND_HEAP_INFO_EXT,
- .pNext = nullptr,
- };
+ {
+ device_buffer* image_heap_buffer = vkdevice::get().get_buffer(image_heap);
- vkCmdBindResourceHeapEXT(vk_command_buffer, &image_bind_heap_info);
+ VkDeviceAddressRangeEXT heap_range {
+ .address = image_heap_buffer->device_address,
+ .size = image_heap_buffer->size,
+ };
+ VkBindHeapInfoEXT bind_heap_info = {
+ .sType = VK_STRUCTURE_TYPE_BIND_HEAP_INFO_EXT,
+ .pNext = nullptr,
+ .heapRange = heap_range,
+ .reservedRangeOffset = 0U,
+ .reservedRangeSize = descriptor_heap_props.minResourceHeapReservedRange,
+ };
- VkBindHeapInfoEXT sampler_bind_heap_info = {
- .sType = VK_STRUCTURE_TYPE_BIND_HEAP_INFO_EXT,
- .pNext = nullptr,
- };
+ vkCmdBindResourceHeapEXT(vk_command_buffer, &bind_heap_info);
+ }
+
+ {
+ device_buffer* sampler_heap_buffer = vkdevice::get().get_buffer(sampler_heap);
+
+ VkDeviceAddressRangeEXT heap_range {
+ .address = sampler_heap_buffer->device_address,
+ .size = sampler_heap_buffer->size,
+ };
+
+ VkBindHeapInfoEXT sampler_bind_heap_info = {
+ .sType = VK_STRUCTURE_TYPE_BIND_HEAP_INFO_EXT,
+ .pNext = nullptr,
+ .heapRange = heap_range,
+ .reservedRangeOffset = 0U,
+ .reservedRangeSize = descriptor_heap_props.minSamplerHeapReservedRange,
+ };
- vkCmdBindSamplerHeapEXT(vk_command_buffer, &sampler_bind_heap_info);
+ vkCmdBindSamplerHeapEXT(vk_command_buffer, &sampler_bind_heap_info);
+ }
}
void command_buffer::stop() const {
@@ -77,9 +97,8 @@ void command_buffer::barrier(handle<device_texture> texture_handle, VkPipelineSt
}
void command_buffer::copy(handle<device_buffer> buffer_handle, ::handle<device_texture> texture_handle, uint64_t offset) const {
- auto& device = vkdevice::get();
- const device_buffer* buffer = device.get_buffer(buffer_handle);
- const device_texture* texture = device.get_texture(texture_handle);
+ const device_buffer* buffer = vkdevice::get().get_buffer(buffer_handle);
+ const device_texture* texture = vkdevice::get().get_texture(texture_handle);
VkImageSubresourceLayers image_subresource_layers{
.aspectMask = texture->aspects,
@@ -106,13 +125,8 @@ void command_buffer::copy(handle<device_buffer> buffer_handle, ::handle<device_t
void graphics_command_buffer::dispatch(const dispatch_params& params, const void* data, size_t size) const {
const device_pipeline* pipeline = vkdevice::get().get_pipeline(params.pipeline);
- // const bindless_model& bindless = vkdevice::get().get_bindingmodel();
-
vkCmdBindPipeline(vk_command_buffer, pipeline->bind_point, pipeline->vk_pipeline);
- // const device_buffer* draw_uniforms = bindless.get_uniform_buffer(UniformTypes::DRAW);
- // constants[UniformTypes::DRAW] = draw_uniforms->device_address + draw_uniforms->offset;
- // vkCmdPushConstants(vk_command_buffer, bindless.global_layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT, 0U, sizeof(constants), &constants);
VkPushDataInfoEXT push_data {
.sType = VK_STRUCTURE_TYPE_PUSH_DATA_INFO_EXT,
.pNext = nullptr,
@@ -124,9 +138,9 @@ void graphics_command_buffer::dispatch(const dispatch_params& params, const void
};
vkCmdPushDataEXT(vk_command_buffer, &push_data);
- auto x = params.group_size.vec.x / params.local_group_size.vec.x;
- auto y = params.group_size.vec.y / params.local_group_size.vec.y;
- auto z = params.group_size.vec.z / params.local_group_size.vec.z;
+ u32 x = params.group_size.vec.x / params.local_group_size.vec.x;
+ u32 y = params.group_size.vec.y / params.local_group_size.vec.y;
+ u32 z = params.group_size.vec.z / params.local_group_size.vec.z;
vkCmdDispatch(vk_command_buffer, x, y, z);
}
@@ -185,26 +199,14 @@ void graphics_command_buffer::begin_renderpass(const renderpass_params& params)
};
vkCmdBeginRendering(vk_command_buffer, &rendering_info);
- // const bindless_model& bindless = vkdevice::get().get_bindingmodel();
- // const device_buffer* pass_uniforms = bindless.get_uniform_buffer(UniformTypes::PASS);
- // constants[UniformTypes::PASS] = pass_uniforms->device_address + pass_uniforms->offset;
-
vkCmdSetScissor(vk_command_buffer, 0U, 1U, &scissor);
vkCmdSetViewport(vk_command_buffer, 0U, 1U, &viewport);
}
void graphics_command_buffer::draw(const draw_params& params, const void* data, size_t size) const {
- auto& device = vkdevice::get();
- const device_pipeline* pipeline = device.get_pipeline(params.pipeline);
-
- // const auto& bindless = device.get_bindingmodel();
-
+ const device_pipeline* pipeline = vkdevice::get().get_pipeline(params.pipeline);
vkCmdBindPipeline(vk_command_buffer, pipeline->bind_point, pipeline->vk_pipeline);
- // const device_buffer* draw_uniforms = bindless.get_uniform_buffer(UniformTypes::DRAW);
- // constants[UniformTypes::DRAW] = draw_uniforms->device_address + draw_uniforms->offset;
- // vkCmdPushConstants(vk_command_buffer, bindless.global_layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT, 0U, sizeof(constants), &constants);
-
VkPushDataInfoEXT push_data {
.sType = VK_STRUCTURE_TYPE_PUSH_DATA_INFO_EXT,
.pNext = nullptr,
@@ -220,17 +222,9 @@ void graphics_command_buffer::draw(const draw_params& params, const void* data,
}
void graphics_command_buffer::draw_indexed(const draw_indexed_params& params, const void* data, size_t size) const {
- auto& device = vkdevice::get();
- const device_pipeline* pipeline = device.get_pipeline(params.pipeline);
-
- // const auto& bindless = device.get_bindingmodel();
-
+ const device_pipeline* pipeline = vkdevice::get().get_pipeline(params.pipeline);
vkCmdBindPipeline(vk_command_buffer, pipeline->bind_point, pipeline->vk_pipeline);
- // const device_buffer* draw_uniforms = bindless.get_uniform_buffer(UniformTypes::DRAW);
- // constants[UniformTypes::DRAW] = draw_uniforms->device_address + draw_uniforms->offset;
- // vkCmdPushConstants(vk_command_buffer, bindless.global_layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT, 0U, sizeof(constants), &constants);
-
VkPushDataInfoEXT push_data {
.sType = VK_STRUCTURE_TYPE_PUSH_DATA_INFO_EXT,
.pNext = nullptr,
@@ -242,7 +236,7 @@ void graphics_command_buffer::draw_indexed(const draw_indexed_params& params, co
};
vkCmdPushDataEXT(vk_command_buffer, &push_data);
- const device_buffer* index_buffer = device.get_buffer(params.index_buffer);
+ const device_buffer* index_buffer = vkdevice::get().get_buffer(params.index_buffer);
vkCmdBindIndexBuffer(vk_command_buffer, index_buffer->vk_buffer, 0U, VK_INDEX_TYPE_UINT16);
vkCmdDrawIndexed(vk_command_buffer, params.vertex_count, params.instance_count, params.index_offset, static_cast<int32_t>(params.vertex_offset), 0U);
}
diff --git a/src/vk-device.cpp b/src/vk-device.cpp
index 988d344..bf18610 100644
--- a/src/vk-device.cpp
+++ b/src/vk-device.cpp
@@ -4,7 +4,58 @@
#include <vk_mem_alloc.h>
-device_semaphore create_semaphore(VkDevice device, const semaphore_desc& desc, const char* name) {
+
+static VkInstance instance;
+static VkPhysicalDevice physical_device;
+static VkPhysicalDeviceProperties2 physical_device_props;
+static VkDevice device;
+
+static constexpr size_t max_images_count = 10000U;
+static constexpr size_t max_samplers_count = 16U;
+static constexpr size_t storage_images_offset = 0U;
+static constexpr size_t sampled_images_offset = max_images_count / 2U;
+
+// TODO: Dont use handle for internally used resources
+handle<device_buffer> image_heap;
+handle<device_buffer> sampler_heap;
+
+static VmaAllocator gpu_allocator;
+
+VkPhysicalDeviceDescriptorHeapPropertiesEXT descriptor_heap_props {
+ .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_HEAP_PROPERTIES_EXT,
+};
+
+void create_heaps(size_t max_images, size_t max_samplers) {
+ // create image heap
+ {
+ image_heap = vkdevice::get().create_buffer({
+ .size = descriptor_heap_props.minResourceHeapReservedRange + max_images * descriptor_heap_props.imageDescriptorSize,
+ .usages = VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT |
+ VK_BUFFER_USAGE_2_DESCRIPTOR_HEAP_BIT_EXT |
+ VK_BUFFER_USAGE_2_TRANSFER_DST_BIT,
+ .memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
+ .memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
+ // .memory_usage = VMA_MEMORY_USAGE_GPU_ONLY,
+ .name = "image descriptor_heap",
+ });
+ }
+
+ // create sampler heap
+ {
+ sampler_heap = vkdevice::get().create_buffer({
+ .size = descriptor_heap_props.minSamplerHeapReservedRange + max_samplers * descriptor_heap_props.samplerDescriptorSize,
+ .usages = VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT |
+ VK_BUFFER_USAGE_2_DESCRIPTOR_HEAP_BIT_EXT |
+ VK_BUFFER_USAGE_2_TRANSFER_DST_BIT,
+ .memory_properties = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
+ .memory_usage = VMA_MEMORY_USAGE_CPU_TO_GPU,
+ // .memory_usage = VMA_MEMORY_USAGE_GPU_ONLY,
+ .name = "sampler descriptor_heap",
+ });
+ }
+}
+
+device_semaphore create_semaphore(const semaphore_desc& desc, const char* name) {
device_semaphore semaphore {
.value = desc.initial_value,
};
@@ -37,7 +88,7 @@ device_semaphore create_semaphore(VkDevice device, const semaphore_desc& desc, c
}
-static VkShaderModule create_shader_module(VkDevice device, uint8_t* code, size_t code_size) {
+static VkShaderModule create_shader_module(uint8_t* code, size_t code_size) {
VkShaderModule shader_module;
VkShaderModuleCreateInfo create_info{
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
@@ -94,7 +145,6 @@ void vkdevice::init() {
create_device();
fence = create_semaphore(
- device,
{
.type = VK_SEMAPHORE_TYPE_TIMELINE,
}, "timeline_semaphore"
@@ -193,7 +243,7 @@ handle<device_buffer> vkdevice::create_buffer(const buffer_desc& desc) {
};
VKCHECK(vmaCreateBuffer(gpu_allocator, &create_info, &alloc_create_info, &device_buffer.vk_buffer, &device_buffer.alloc, &alloc_info));
- vmaSetAllocationName(render_device.get_allocator(), device_buffer.alloc, desc.name);
+ vmaSetAllocationName(gpu_allocator, device_buffer.alloc, desc.name);
if ((desc.usages & VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT) != 0U) {
VkBufferDeviceAddressInfo address_info {
@@ -218,7 +268,7 @@ handle<device_pipeline> vkdevice::create_graphics_pipeline(const graphics_pipeli
.pNext = nullptr,
.flags = 0U,
.stage = VK_SHADER_STAGE_VERTEX_BIT,
- .module = create_shader_module(device, desc.vs_code, desc.vs_code_size),
+ .module = create_shader_module(desc.vs_code, desc.vs_code_size),
.pName = "main",
.pSpecializationInfo = nullptr,
},
@@ -227,7 +277,7 @@ handle<device_pipeline> vkdevice::create_graphics_pipeline(const graphics_pipeli
.pNext = nullptr,
.flags = 0U,
.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
- .module = create_shader_module(device, desc.fs_code, desc.fs_code_size),
+ .module = create_shader_module(desc.fs_code, desc.fs_code_size),
.pName = "main",
.pSpecializationInfo = nullptr,
},
@@ -320,9 +370,15 @@ handle<device_pipeline> vkdevice::create_graphics_pipeline(const graphics_pipeli
.stencilAttachmentFormat = VK_FORMAT_UNDEFINED,
};
+ VkPipelineCreateFlags2CreateInfo create_flags2 {
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_CREATE_FLAGS_2_CREATE_INFO,
+ .pNext = &pipeline_rendering_create_info,
+ .flags = VK_PIPELINE_CREATE_2_DESCRIPTOR_HEAP_BIT_EXT,
+ };
+
VkGraphicsPipelineCreateInfo create_info{
.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
- .pNext = &pipeline_rendering_create_info,
+ .pNext = &create_flags2,
.flags = 0U,
.stageCount = sizeof(shader_stages_create_info) / sizeof(VkPipelineShaderStageCreateInfo),
.pStages = shader_stages_create_info,
@@ -372,14 +428,20 @@ handle<device_pipeline> vkdevice::create_compute_pipeline(const compute_pipeline
.pNext = nullptr,
.flags = 0U,
.stage = VK_SHADER_STAGE_COMPUTE_BIT,
- .module = create_shader_module(device, desc.cs_code, desc.cs_code_size),
+ .module = create_shader_module(desc.cs_code, desc.cs_code_size),
.pName = "main",
.pSpecializationInfo = nullptr,
};
+ VkPipelineCreateFlags2CreateInfo create_flags2 {
+ .sType = VK_STRUCTURE_TYPE_PIPELINE_CREATE_FLAGS_2_CREATE_INFO,
+ .pNext = nullptr,
+ .flags = VK_PIPELINE_CREATE_2_DESCRIPTOR_HEAP_BIT_EXT,
+ };
+
VkComputePipelineCreateInfo create_info{
.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
- .pNext = nullptr,
+ .pNext = &create_flags2,
.flags = 0U,
.stage = stage_create_info,
// .layout = bindless.global_layout,
@@ -428,13 +490,11 @@ handle<device_surface> vkdevice::create_surface(const surface_desc& desc) {
for (uint32_t index = 0u; index < device_surface.image_count; index++) {
device_surface.acquire_semaphores[index] = create_semaphore(
- device,
{
.type = VK_SEMAPHORE_TYPE_BINARY,
}, "acquire_semaphore"
);
device_surface.submit_semaphores[index] = create_semaphore(
- device,
{
.type = VK_SEMAPHORE_TYPE_BINARY,
}, "submit_semaphore"
@@ -802,9 +862,6 @@ void vkdevice::create_instance() {
void vkdevice::create_device() {
// pick physical device
// TODO: change put this in another scope
- VkPhysicalDeviceDescriptorHeapPropertiesEXT descriptor_heap_props {
- .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_HEAP_PROPERTIES_EXT,
- };
{
u32 physical_devices_count = 0U;
vkEnumeratePhysicalDevices(instance, &physical_devices_count, nullptr);
@@ -822,6 +879,7 @@ void vkdevice::create_device() {
VkPhysicalDevice physical_dev = physical_devices[physical_device_index];
if (device_support_features(physical_dev)) {
physical_device = physical_dev;
+
break;
}
}
@@ -863,6 +921,7 @@ void vkdevice::create_device() {
VK_KHR_SWAPCHAIN_EXTENSION_NAME,
VK_EXT_DESCRIPTOR_HEAP_EXTENSION_NAME,
VK_KHR_MAINTENANCE_5_EXTENSION_NAME,
+ VK_KHR_SHADER_UNTYPED_POINTERS_EXTENSION_NAME,
};
VkPhysicalDeviceVulkan12Features physical_device_12_features{
@@ -884,9 +943,22 @@ void vkdevice::create_device() {
.dynamicRendering = VK_TRUE,
};
+ VkPhysicalDeviceDescriptorHeapFeaturesEXT descriptor_heap_features {
+ .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_HEAP_FEATURES_EXT,
+ .pNext = &physical_device_13_features,
+ .descriptorHeap = VK_TRUE,
+ .descriptorHeapCaptureReplay = VK_TRUE,
+ };
+
+ VkPhysicalDeviceShaderUntypedPointersFeaturesKHR shader_untyped_pointers_features {
+ .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_UNTYPED_POINTERS_FEATURES_KHR,
+ .pNext = &descriptor_heap_features,
+ .shaderUntypedPointers = VK_TRUE,
+ };
+
VkDeviceCreateInfo create_info{
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
- .pNext = &physical_device_13_features,
+ .pNext = &shader_untyped_pointers_features,
.flags = 0U,
.queueCreateInfoCount = static_cast<uint32_t>(QueueType::MAX),
.pQueueCreateInfos = queue_create_infos,
@@ -938,33 +1010,7 @@ void vkdevice::create_device() {
VKCHECK(vmaCreateAllocator(&allocator_create_info, &gpu_allocator));
}
- create_heaps(descriptor_heap_props);
-}
-
-void vkdevice::create_heaps(VkPhysicalDeviceDescriptorHeapPropertiesEXT& descriptor_heap_props) {
- // create image heap
- {
- sampler_heap = create_buffer({
- .size = descriptor_heap_props.minResourceHeapReservedRange + max_images_count * descriptor_heap_props.imageDescriptorSize,
- .usages = VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT |
- VK_BUFFER_USAGE_2_DESCRIPTOR_HEAP_BIT_EXT |
- VK_BUFFER_USAGE_2_TRANSFER_DST_BIT,
- .memory_usage = VMA_MEMORY_USAGE_GPU_ONLY,
- .name = "image descriptor_heap",
- });
- }
-
- // create sampler heap
- {
- sampler_heap = create_buffer({
- .size = descriptor_heap_props.minSamplerHeapReservedRange + max_samplers_count * descriptor_heap_props.samplerDescriptorSize,
- .usages = VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT |
- VK_BUFFER_USAGE_2_DESCRIPTOR_HEAP_BIT_EXT |
- VK_BUFFER_USAGE_2_TRANSFER_DST_BIT,
- .memory_usage = VMA_MEMORY_USAGE_GPU_ONLY,
- .name = "sampler descriptor_heap",
- });
- }
+ create_heaps(max_images_count, max_samplers_count);
}
@@ -1026,7 +1072,6 @@ idlist<> device_sampler::sampler_indices = {};
void device_texture::init(const texture_desc& desc) {
auto& render_device = vkdevice::get();
- auto* device = render_device.get_device();
vk_image = desc.vk_image;
format = desc.format;
@@ -1073,8 +1118,8 @@ void device_texture::init(const texture_desc& desc) {
.pUserData = nullptr,
};
- VKCHECK(vmaCreateImage(render_device.get_allocator(), &create_info, &alloc_create_info, &vk_image, &alloc, nullptr));
- vmaSetAllocationName(render_device.get_allocator(), alloc, desc.name);
+ VKCHECK(vmaCreateImage(gpu_allocator, &create_info, &alloc_create_info, &vk_image, &alloc, nullptr));
+ vmaSetAllocationName(gpu_allocator, alloc, desc.name);
}
if (desc.name) {
@@ -1129,6 +1174,7 @@ void device_texture::init(const texture_desc& desc) {
.layout = VK_IMAGE_LAYOUT_GENERAL,
};
+ device_buffer* image_heap_buffer = render_device.get_buffer(image_heap);
u32 descriptors_count = 0U;
VkResourceDescriptorInfoEXT resource_descriptor_infos[2U];
VkHostAddressRangeEXT resources_address[2U];
@@ -1142,10 +1188,11 @@ void device_texture::init(const texture_desc& desc) {
},
};
- // resource_address[descriptors_count] = {
- // .address = storage_indices.add(),
- // .size = ,
- // }
+ storage_index = storage_indices.add();
+ resources_address[descriptors_count] = {
+ .address = ((u8*)image_heap_buffer->mapped_ptr) + descriptor_heap_props.imageDescriptorSize * (storage_index.id + storage_images_offset),
+ .size = descriptor_heap_props.imageDescriptorSize,
+ };
descriptors_count++;
}
@@ -1159,10 +1206,11 @@ void device_texture::init(const texture_desc& desc) {
},
};
- // resource_address[descriptors_count] = {
- // .address = sampled_indices.add(),
- // .size = ,
- // }
+ sampled_index = sampled_indices.add();
+ resources_address[descriptors_count] = {
+ .address = ((u8*)image_heap_buffer->mapped_ptr) + descriptor_heap_props.imageDescriptorSize * (sampled_index.id + sampled_images_offset),
+ .size = descriptor_heap_props.imageDescriptorSize,
+ };
descriptors_count++;
}
@@ -1171,10 +1219,6 @@ void device_texture::init(const texture_desc& desc) {
}
void device_texture::release() {
- vkdevice& render_device = vkdevice::get();
- VkDevice device = render_device.get_device();
- auto* gpu_allocator = render_device.get_allocator();
-
if (alloc != nullptr) {
vmaDestroyImage(gpu_allocator, vk_image, alloc);
}
@@ -1200,8 +1244,7 @@ void device_texture::create_views() {
void device_sampler::init(const sampler_desc& desc) {
- auto& render_device = vkdevice::get();
- auto* device = render_device.get_device();
+ vkdevice& render_device = vkdevice::get();
VkSamplerCreateInfo sampler_create_info{
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
@@ -1228,22 +1271,14 @@ void device_sampler::init(const sampler_desc& desc) {
sampler_index = sampler_indices.add();
- // VkWriteDescriptorSet write_descriptor_set{
- // .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
- // .pNext = nullptr,
- // .dstSet = bindless.sets[BindlessSetType::GLOBAL],
- // .dstBinding = 1U,
- // .dstArrayElement = sampler_index.id,
- // .descriptorCount = 1U,
- // .descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
- // .pImageInfo = images_info,
- // .pBufferInfo = nullptr,
- // .pTexelBufferView = nullptr,
- // });
-
- // TODO: Write samplers to heap
// TODO: Create previously immutable samplers
- VKCHECK(vkWriteSamplerDescriptorsEXT());
+ device_buffer* sampler_heap_buffer = render_device.get_buffer(sampler_heap);
+
+ VkHostAddressRangeEXT destination_address {
+ .address = ((u8*)sampler_heap_buffer->mapped_ptr) + descriptor_heap_props.samplerDescriptorSize * sampler_index.id,
+ .size = descriptor_heap_props.samplerDescriptorSize,
+ };
+ VKCHECK(vkWriteSamplerDescriptorsEXT(device, 1U, &sampler_create_info, &destination_address));
}