From 3c8f0476cfdd2894544adbed2edbc67660704dfa Mon Sep 17 00:00:00 2001 From: Fabian Schmidt Date: Fri, 11 Oct 2024 14:09:14 +0200 Subject: [PATCH] Cube utils rework (#75) * Slimmer cube-utils, dropping buffer-input * less command-pools --- include/vierkant/cubemap_utils.hpp | 5 +- shaders/cube/cube.vert | 25 ++++++++- src/Rasterizer.cpp | 2 +- src/cubemap_utils.cpp | 81 +++++++++++------------------- 4 files changed, 56 insertions(+), 57 deletions(-) diff --git a/include/vierkant/cubemap_utils.hpp b/include/vierkant/cubemap_utils.hpp index 883d38b4..ae61fb2a 100644 --- a/include/vierkant/cubemap_utils.hpp +++ b/include/vierkant/cubemap_utils.hpp @@ -13,7 +13,6 @@ namespace vierkant struct cube_pipeline_t { vierkant::DevicePtr device; - vierkant::CommandPoolPtr command_pool; vierkant::Framebuffer framebuffer; vierkant::Rasterizer renderer; vierkant::drawable_t drawable; @@ -25,12 +24,14 @@ struct cube_pipeline_t * @brief Create assets for a cube-pipeline. * * @param device + * @param command_pool * @param size * @param color_format * @param depth * @return a struct grouping assets for a cube-pipeline. */ -cube_pipeline_t create_cube_pipeline(const vierkant::DevicePtr &device, uint32_t size, VkFormat color_format, +cube_pipeline_t create_cube_pipeline(const vierkant::DevicePtr &device, const vierkant::CommandPoolPtr &command_pool, + uint32_t size, VkFormat color_format, VkQueue queue, bool depth = false, VkImageUsageFlags usage_flags = 0, const vierkant::DescriptorPoolPtr &descriptor_pool = nullptr); diff --git a/shaders/cube/cube.vert b/shaders/cube/cube.vert index fdd109b4..110d2f75 100644 --- a/shaders/cube/cube.vert +++ b/shaders/cube/cube.vert @@ -11,7 +11,28 @@ layout(std140, binding = 0) uniform ubo_matrices mat4 u_projection_matrix; }; -layout(location = ATTRIB_POSITION) in vec3 a_position; +const vec3 half_extents = vec3(0.5); + +const vec3 base_vertices[8] = +{ + vec3(-half_extents.x, -half_extents.y, half_extents.z), // bottom left front 0 + vec3(half_extents.x, -half_extents.y, half_extents.z), // bottom right front 1 + vec3(half_extents.x, -half_extents.y, -half_extents.z), // bottom right back 2 + vec3(-half_extents.x, -half_extents.y, -half_extents.z), // bottom left back 3 + vec3(-half_extents.x, half_extents.y, half_extents.z), // top left front 4 + vec3(half_extents.x, half_extents.y, half_extents.z), // top right front 5 + vec3(half_extents.x, half_extents.y, -half_extents.z), // top right back 6 + vec3(-half_extents.x, half_extents.y, -half_extents.z), // top left back 7 +}; + +uint indices[36] = { + 0, 1, 5, 5, 4, 0, // front + 1, 2, 6, 6, 5, 1, // right + 2, 3, 7, 7, 6, 2, // back + 3, 0, 4, 4, 7, 3, // left + 4, 5, 6, 6, 7, 4, // top + 3, 2, 1, 1, 0, 3, // bottom +}; layout(location = 0) out VertexData { @@ -23,7 +44,7 @@ void main() // amplify geometry for all cube-faces via instancing gl_Layer = gl_InstanceIndex; - vec4 tmp = u_model_matrix * vec4(a_position, 1.0); + vec4 tmp = u_model_matrix * vec4(base_vertices[indices[gl_VertexIndex]], 1.0); vertex_out.eye_vec = vec3(tmp.x, -tmp.y, tmp.z); gl_Position = u_projection_matrix * u_view_matrix[gl_Layer] * tmp; } diff --git a/src/Rasterizer.cpp b/src/Rasterizer.cpp index 732000b8..48583b4a 100644 --- a/src/Rasterizer.cpp +++ b/src/Rasterizer.cpp @@ -453,7 +453,7 @@ void Rasterizer::render(VkCommandBuffer command_buffer, frame_assets_t &frame_as frame_assets.indirect_bundle.num_draws++; draw_command->vertexCount = drawable->num_vertices; - draw_command->instanceCount = 1; + draw_command->instanceCount = drawable->num_instances; draw_command->firstVertex = drawable->vertex_offset; draw_command->firstInstance = indexed_drawable.object_index; } diff --git a/src/cubemap_utils.cpp b/src/cubemap_utils.cpp index eb96f392..a6fdd1d5 100644 --- a/src/cubemap_utils.cpp +++ b/src/cubemap_utils.cpp @@ -11,8 +11,9 @@ struct img_copy_assets_t vierkant::FencePtr fence; }; -vierkant::ImagePtr cubemap_generate_mip_maps(const vierkant::cube_pipeline_t &cube, VkQueue queue, VkFormat format, - img_copy_assets_t &img_copy_asset, std::vector &fences) +vierkant::ImagePtr cubemap_generate_mip_maps(const vierkant::cube_pipeline_t &cube, VkCommandPool pool, VkQueue queue, + VkFormat format, img_copy_assets_t &img_copy_asset, + std::vector &fences) { vierkant::Image::Format ret_fmt = {}; ret_fmt.extent = cube.color_image->extent(); @@ -28,7 +29,7 @@ vierkant::ImagePtr cubemap_generate_mip_maps(const vierkant::cube_pipeline_t &cu auto mipmap_cube = vierkant::Image::create(cube.device, ret_fmt); // copy image into mipmap-chain - img_copy_asset.command_buffer = vierkant::CommandBuffer(cube.device, cube.command_pool.get()); + img_copy_asset.command_buffer = vierkant::CommandBuffer(cube.device, pool); img_copy_asset.fence = vierkant::create_fence(cube.device); img_copy_asset.command_buffer.begin(); @@ -71,7 +72,9 @@ vierkant::ImagePtr cubemap_neutral_environment(const vierkant::DevicePtr &device bool mipmap, VkFormat format) { VkImageUsageFlags flags = mipmap ? VK_IMAGE_USAGE_TRANSFER_SRC_BIT : VK_IMAGE_USAGE_SAMPLED_BIT; - auto cube = vierkant::create_cube_pipeline(device, size, format, queue, false, flags); + auto command_pool = vierkant::create_command_pool(device, vierkant::Device::Queue::GRAPHICS, + VK_COMMAND_POOL_CREATE_TRANSIENT_BIT); + auto cube = vierkant::create_cube_pipeline(device, command_pool, size, format, queue, false, flags); auto ret_img = cube.color_image; @@ -87,7 +90,10 @@ vierkant::ImagePtr cubemap_neutral_environment(const vierkant::DevicePtr &device fences.push_back(cube.framebuffer.submit({cmd_buf}, queue)); img_copy_assets_t image_copy_asset; - if(mipmap) { ret_img = cubemap_generate_mip_maps(cube, queue, format, image_copy_asset, fences); } + if(mipmap) + { + ret_img = cubemap_generate_mip_maps(cube, command_pool.get(), queue, format, image_copy_asset, fences); + } // mandatory to sync here vkWaitForFences(device->handle(), fences.size(), fences.data(), VK_TRUE, std::numeric_limits::max()); @@ -101,9 +107,10 @@ vierkant::ImagePtr cubemap_from_panorama(const vierkant::DevicePtr &device, cons VkQueue queue, uint32_t size, bool mipmap, VkFormat format) { if(!panorama_img) { return nullptr; } - VkImageUsageFlags flags = mipmap ? VK_IMAGE_USAGE_TRANSFER_SRC_BIT : VK_IMAGE_USAGE_SAMPLED_BIT; - auto cube = vierkant::create_cube_pipeline(device, size, format, queue, false, flags); + auto command_pool = vierkant::create_command_pool(device, vierkant::Device::Queue::GRAPHICS, + VK_COMMAND_POOL_CREATE_TRANSIENT_BIT); + auto cube = vierkant::create_cube_pipeline(device, command_pool, size, format, queue, false, flags); auto ret_img = cube.color_image; @@ -126,7 +133,10 @@ vierkant::ImagePtr cubemap_from_panorama(const vierkant::DevicePtr &device, cons fences.push_back(cube.framebuffer.submit({cmd_buf}, queue)); img_copy_assets_t image_copy_asset; - if(mipmap) { ret_img = cubemap_generate_mip_maps(cube, queue, format, image_copy_asset, fences); } + if(mipmap) + { + ret_img = cubemap_generate_mip_maps(cube, command_pool.get(), queue, format, image_copy_asset, fences); + } // mandatory to sync here vkWaitForFences(device->handle(), fences.size(), fences.data(), VK_TRUE, std::numeric_limits::max()); @@ -140,7 +150,10 @@ vierkant::ImagePtr create_convolution_lambert(const DevicePtr &device, const Ima VkFormat format, VkQueue queue) { // create a cube-pipeline - auto cube = vierkant::create_cube_pipeline(device, size, format, queue, false, VK_IMAGE_USAGE_SAMPLED_BIT); + auto command_pool = vierkant::create_command_pool(device, vierkant::Device::Queue::GRAPHICS, + VK_COMMAND_POOL_CREATE_TRANSIENT_BIT); + auto cube = vierkant::create_cube_pipeline(device, command_pool, size, format, queue, false, + VK_IMAGE_USAGE_SAMPLED_BIT); cube.drawable.pipeline_format.shader_stages[VK_SHADER_STAGE_FRAGMENT_BIT] = vierkant::create_shader_module(device, vierkant::shaders::pbr::convolve_lambert_frag); @@ -205,7 +218,7 @@ vierkant::ImagePtr create_convolution_ggx(const DevicePtr &device, const ImagePt auto &cube = cube_pipelines[lvl]; // create a cube-pipeline - cube = vierkant::create_cube_pipeline(device, size, format, queue, false, + cube = vierkant::create_cube_pipeline(device, command_pool, size, format, queue, false, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, descriptor_pool); cube.drawable.pipeline_format.shader_stages[VK_SHADER_STAGE_FRAGMENT_BIT] = frag_module; @@ -235,7 +248,7 @@ vierkant::ImagePtr create_convolution_ggx(const DevicePtr &device, const ImagePt // copy image into mipmap-chain img_copy_assets_t &image_copy_asset = image_copy_assets[lvl]; - image_copy_asset.command_buffer = vierkant::CommandBuffer(device, cube.command_pool.get()); + image_copy_asset.command_buffer = vierkant::CommandBuffer(device, command_pool.get()); image_copy_asset.fence = vierkant::create_fence(device); image_copy_asset.command_buffer.begin(); @@ -278,13 +291,10 @@ vierkant::ImagePtr create_convolution_ggx(const DevicePtr &device, const ImagePt //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -cube_pipeline_t create_cube_pipeline(const vierkant::DevicePtr &device, uint32_t size, VkFormat color_format, - VkQueue queue, bool depth, VkImageUsageFlags usage_flags, - const vierkant::DescriptorPoolPtr &descriptor_pool) +cube_pipeline_t create_cube_pipeline(const vierkant::DevicePtr &device, const vierkant::CommandPoolPtr &command_pool, + uint32_t size, VkFormat color_format, VkQueue queue, bool depth, + VkImageUsageFlags usage_flags, const vierkant::DescriptorPoolPtr &descriptor_pool) { - auto command_pool = vierkant::create_command_pool(device, vierkant::Device::Queue::GRAPHICS, - VK_COMMAND_POOL_CREATE_TRANSIENT_BIT); - // framebuffer image-format vierkant::Image::Format img_fmt = {}; img_fmt.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | usage_flags; @@ -303,11 +313,8 @@ cube_pipeline_t create_cube_pipeline(const vierkant::DevicePtr &device, uint32_t fb_create_info.queue = queue; auto cube_fb = vierkant::Framebuffer(device, fb_create_info); - // create cube pipeline with vertex- + geometry-stages - // render vierkant::Rasterizer::create_info_t cuber_render_create_info = {}; - // cuber_render_create_info.renderpass = cube_fb.renderpass(); cuber_render_create_info.num_frames_in_flight = 1; cuber_render_create_info.sample_count = VK_SAMPLE_COUNT_1_BIT; cuber_render_create_info.viewport.width = static_cast(cube_fb.extent().width); @@ -320,37 +327,8 @@ cube_pipeline_t create_cube_pipeline(const vierkant::DevicePtr &device, uint32_t vierkant::drawable_t drawable = {}; drawable.pipeline_format.shader_stages[VK_SHADER_STAGE_VERTEX_BIT] = vierkant::create_shader_module(device, vierkant::shaders::cube::cube_vert); - - auto cmd_buffer = vierkant::CommandBuffer(device, command_pool.get()); - cmd_buffer.begin(); - - auto box = vierkant::Geometry::Box(); - box->colors.clear(); - box->tex_coords.clear(); - box->normals.clear(); - box->tangents.clear(); - - vierkant::Mesh::create_info_t mesh_create_info = {}; - mesh_create_info.command_buffer = cmd_buffer.handle(); - mesh_create_info.staging_buffer = - vierkant::Buffer::create(device, nullptr, 0, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VMA_MEMORY_USAGE_CPU_ONLY); - - drawable.mesh = vierkant::Mesh::create_from_geometry(device, box, mesh_create_info); - cmd_buffer.submit(queue, true); - drawable.num_instances = 6; - const auto &mesh_entry = drawable.mesh->entries.front(); - const auto &lod_0 = mesh_entry.lods.front(); - drawable.base_index = lod_0.base_index; - drawable.num_indices = lod_0.num_indices; - drawable.vertex_offset = mesh_entry.vertex_offset; - drawable.num_vertices = mesh_entry.num_vertices; - - drawable.pipeline_format.binding_descriptions = - vierkant::create_binding_descriptions(drawable.mesh->vertex_attribs); - drawable.pipeline_format.attribute_descriptions = - vierkant::create_attribute_descriptions(drawable.mesh->vertex_attribs); - drawable.pipeline_format.primitive_topology = mesh_entry.primitive_type; + drawable.num_vertices = 36; drawable.pipeline_format.blend_state.blendEnable = false; drawable.pipeline_format.depth_test = false; drawable.pipeline_format.depth_write = false; @@ -371,14 +349,13 @@ cube_pipeline_t create_cube_pipeline(const vierkant::DevicePtr &device, uint32_t vierkant::descriptor_t desc_matrices = {}; desc_matrices.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - desc_matrices.stage_flags = VK_SHADER_STAGE_VERTEX_BIT;//VK_SHADER_STAGE_GEOMETRY_BIT; + desc_matrices.stage_flags = VK_SHADER_STAGE_VERTEX_BIT; desc_matrices.buffers = {vierkant::Buffer::create(device, &ubo_data, sizeof(ubo_data), VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VMA_MEMORY_USAGE_CPU_TO_GPU)}; drawable.descriptors[0] = desc_matrices; cube_pipeline_t ret = {}; ret.device = device; - ret.command_pool = command_pool; ret.renderer = std::move(cube_render); ret.drawable = std::move(drawable); ret.color_image = cube_fb.color_attachment(0);