From 6db256b8eb4cc45c5296070ae7353e65398d121d Mon Sep 17 00:00:00 2001 From: ladevieq Date: Tue, 18 Aug 2026 00:43:03 +0200 Subject: Finished descriptor heaps implementation --- include/scene.hpp | 12 +-- include/vk-bindless.hpp | 49 --------- include/vk-device.hpp | 26 ----- shaders/api-test-ui.frag | 25 ++--- shaders/compute.comp | 54 ++++------ shaders/include/ray.h | 54 +++++----- shaders/test.comp | 20 ++-- shaders/tonemapping.comp | 38 ++----- shaders/transmittance_lut.comp | 7 +- src/main.cpp | 191 ++++++++++++++------------------- src/scene.cpp | 59 +++++----- src/vk-bindless.cpp | 238 ----------------------------------------- src/vk-command-buffer.cpp | 88 +++++++-------- src/vk-device.cpp | 183 ++++++++++++++++++------------- 14 files changed, 341 insertions(+), 703 deletions(-) delete mode 100644 include/vk-bindless.hpp delete mode 100644 src/vk-bindless.cpp 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 bvh_buffer_handle; handle 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 - -#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 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 buffers, handle wait_handle, handle signal_handle, handle fence_handle); uint32_t acquire_image_index(handle surface_handle); uint64_t submit_before_present(handle 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(QueueType::MAX)]; - VkInstance instance; - VkPhysicalDevice physical_device; - VkPhysicalDeviceProperties2 physical_device_props; - VkDevice device; - - handle image_heap; // TODO: Dont use handle for internally used resources - handle 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 surface_handle = device.create_surface({ + handle 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 staging_buffer_handle = device.create_buffer({ + const handle 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 vertex_buffer_handle = device.create_buffer({ + const handle 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 index_buffer_handle = device.create_buffer({ + const handle 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 compute = device.create_compute_pipeline({ + handle 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 raytracing = device.create_compute_pipeline({ + handle 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 tonemapping = device.create_compute_pipeline({ + handle 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 graphics = device.create_graphics_pipeline({ + handle 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 transmittance_lut_compute = device.create_compute_pipeline({ + handle 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 gpu_texture_handle = device.create_texture({ + const handle gpu_texture_handle = render_device.create_texture({ .width = static_cast(image_width), .height = static_cast(image_height), #if VK @@ -351,7 +350,7 @@ int main() { #endif }); - const handle second_texture = device.create_texture({ + const handle second_texture = render_device.create_texture({ .width = static_cast(image_width), .height = static_cast(image_height), #if VK @@ -366,7 +365,7 @@ int main() { #endif }); - const handle output_texture_handle = device.create_texture({ + const handle output_texture_handle = render_device.create_texture({ .width = static_cast(image_width), .height = static_cast(image_height), #if VK @@ -380,7 +379,7 @@ int main() { #endif }); - const handle ui_texture_handle = device.create_texture({ + const handle ui_texture_handle = render_device.create_texture({ .width = static_cast(atlas_width), .height = static_cast(atlas_height), #if VK @@ -396,7 +395,7 @@ int main() { .name = "glyph atlas" }); - const handle acc_handle = device.create_texture({ + const handle acc_handle = render_device.create_texture({ .width = static_cast(window_width), .height = static_cast(window_height), #if VK @@ -412,7 +411,7 @@ int main() { .name = "accumulation texture" }); - const handle result_handle = device.create_texture({ + const handle result_handle = render_device.create_texture({ .width = static_cast(window_width), .height = static_cast(window_height), #if VK @@ -428,7 +427,7 @@ int main() { .name = "output texture" }); - const handle transmittance_lut_handle = device.create_texture({ + const handle transmittance_lut_handle = render_device.create_texture({ .width = static_cast(1024), .height = static_cast(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(static_cast(ui_texture->get_sampled_index()))); @@ -457,10 +456,10 @@ int main() { #if VK std::array 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 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(); - } 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(); - } 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(); - // memcpy(static_cast(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(); - // 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(); - } 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_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 indices; @@ -151,12 +148,12 @@ scene::scene(const camera& cam, uint32_t width, uint32_t height) }); if (material.base_color_texture.id != handle::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::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 texture_handle, VkPipelineSt } void command_buffer::copy(handle buffer_handle, ::handle 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 buffer_handle, ::handlebind_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(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 -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 image_heap; +handle 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 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 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 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 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 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 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(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)); } -- cgit v1.3