ci(amd64/clang/lsan): fix leak sanitizer errors #57
					 15 changed files with 273 additions and 199 deletions
				
			
		
							
								
								
									
										252
									
								
								.drone.yml
									
										
									
									
									
								
							
							
						
						
									
										252
									
								
								.drone.yml
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,139 +1,139 @@
 | 
			
		|||
---
 | 
			
		||||
# kind: pipeline
 | 
			
		||||
# type: exec
 | 
			
		||||
# name: amd64 — msvc
 | 
			
		||||
# trigger:
 | 
			
		||||
#   branch:
 | 
			
		||||
#   - main
 | 
			
		||||
# platform:
 | 
			
		||||
#   os: windows
 | 
			
		||||
#   arch: amd64
 | 
			
		||||
#
 | 
			
		||||
# steps:
 | 
			
		||||
# - name: unit tests
 | 
			
		||||
#   shell: powershell
 | 
			
		||||
#   commands: 
 | 
			
		||||
#     - ./tools/ci/amd64/msvc/unit_tests.ps1
 | 
			
		||||
#
 | 
			
		||||
# ---
 | 
			
		||||
kind: pipeline
 | 
			
		||||
type: exec
 | 
			
		||||
name: amd64 — msvc
 | 
			
		||||
trigger:
 | 
			
		||||
  branch:
 | 
			
		||||
  - main
 | 
			
		||||
platform:
 | 
			
		||||
  os: windows
 | 
			
		||||
  arch: amd64
 | 
			
		||||
 | 
			
		||||
steps:
 | 
			
		||||
- name: unit tests
 | 
			
		||||
  shell: powershell
 | 
			
		||||
  commands: 
 | 
			
		||||
    - ./tools/ci/amd64/msvc/unit_tests.ps1
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
kind: pipeline
 | 
			
		||||
type: docker
 | 
			
		||||
name: amd64 — gcc
 | 
			
		||||
trigger:
 | 
			
		||||
  branch:
 | 
			
		||||
  - main
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
steps:
 | 
			
		||||
# - name: unit tests
 | 
			
		||||
#   image: ci:latest
 | 
			
		||||
#   pull: if-not-exists
 | 
			
		||||
#   commands:
 | 
			
		||||
#     - ./tools/ci/amd64/gcc/unit_tests.sh
 | 
			
		||||
#
 | 
			
		||||
- name: unit tests
 | 
			
		||||
  image: ci:latest
 | 
			
		||||
  pull: if-not-exists
 | 
			
		||||
  commands:
 | 
			
		||||
    - ./tools/ci/amd64/gcc/unit_tests.sh
 | 
			
		||||
 | 
			
		||||
- name: valgrind
 | 
			
		||||
  image: ci:latest 
 | 
			
		||||
  pull: if-not-exists
 | 
			
		||||
  commands:
 | 
			
		||||
    - ./tools/ci/amd64/gcc/valgrind.sh
 | 
			
		||||
#
 | 
			
		||||
# ---
 | 
			
		||||
# kind: pipeline
 | 
			
		||||
# type: docker
 | 
			
		||||
# name: amd64 — clang
 | 
			
		||||
# trigger:
 | 
			
		||||
#   branch:
 | 
			
		||||
#   - main
 | 
			
		||||
#
 | 
			
		||||
# steps:
 | 
			
		||||
# - name: code coverage
 | 
			
		||||
#   image: ci:latest
 | 
			
		||||
#   pull: if-not-exists
 | 
			
		||||
#   environment:
 | 
			
		||||
#     CODECOV_TOKEN:
 | 
			
		||||
#       from_secret: CODECOV_TOKEN 
 | 
			
		||||
#   commands:
 | 
			
		||||
#     - ./tools/ci/amd64/clang/coverage.sh
 | 
			
		||||
#
 | 
			
		||||
# - name: leak sanitizer
 | 
			
		||||
#   image: ci:latest 
 | 
			
		||||
#   pull: if-not-exists
 | 
			
		||||
#   commands:
 | 
			
		||||
#     - ./tools/ci/amd64/clang/lsan.sh
 | 
			
		||||
#
 | 
			
		||||
# - name: memory sanitizer
 | 
			
		||||
#   image: ci:latest
 | 
			
		||||
#   pull: if-not-exists
 | 
			
		||||
#   commands:
 | 
			
		||||
#     - ./tools/ci/amd64/clang/msan.sh
 | 
			
		||||
#
 | 
			
		||||
# ---
 | 
			
		||||
# kind: pipeline
 | 
			
		||||
# type: docker
 | 
			
		||||
# name: static analysis
 | 
			
		||||
# trigger:
 | 
			
		||||
#   branch:
 | 
			
		||||
#   - main
 | 
			
		||||
#
 | 
			
		||||
# steps:
 | 
			
		||||
# - name: clang tidy
 | 
			
		||||
#   image: ci:latest 
 | 
			
		||||
#   pull: if-not-exists
 | 
			
		||||
#   privileged: true
 | 
			
		||||
#   commands:
 | 
			
		||||
#     - ./tools/ci/static_analysis/clang_tidy.sh
 | 
			
		||||
#
 | 
			
		||||
# - name: clang format
 | 
			
		||||
#   image: ci:latest 
 | 
			
		||||
#   pull: if-not-exists
 | 
			
		||||
#   commands:
 | 
			
		||||
#     - ./tools/ci/static_analysis/clang_format.sh
 | 
			
		||||
#
 | 
			
		||||
# ---
 | 
			
		||||
# kind: pipeline
 | 
			
		||||
# type: docker 
 | 
			
		||||
# name: documentation — development
 | 
			
		||||
# node:
 | 
			
		||||
#   environment: ryali
 | 
			
		||||
# trigger:
 | 
			
		||||
#   branch:
 | 
			
		||||
#   - main
 | 
			
		||||
#
 | 
			
		||||
# steps:
 | 
			
		||||
# - name: build and deploy
 | 
			
		||||
#   image: documentation:latest
 | 
			
		||||
#   pull: if-not-exists
 | 
			
		||||
#   commands:
 | 
			
		||||
#     - pwd
 | 
			
		||||
#     - cd docs
 | 
			
		||||
#     - mkdir generated
 | 
			
		||||
#     - touch generated/changelogs.rst
 | 
			
		||||
#     - touch generated/api.rst
 | 
			
		||||
#     - sphinx-build -M html . .
 | 
			
		||||
#
 | 
			
		||||
#     - rm -rf /light_docs_dev/*
 | 
			
		||||
#     - mv ./html/* /light_docs_dev/
 | 
			
		||||
#
 | 
			
		||||
# ---
 | 
			
		||||
#
 | 
			
		||||
# kind: pipeline
 | 
			
		||||
# type: docker
 | 
			
		||||
# name: documentation — production
 | 
			
		||||
# node:
 | 
			
		||||
#   environment: ryali
 | 
			
		||||
# trigger:
 | 
			
		||||
#   event:
 | 
			
		||||
#   - tag
 | 
			
		||||
#
 | 
			
		||||
# steps:
 | 
			
		||||
# - name: build and deploy
 | 
			
		||||
#   image: documentation:latest
 | 
			
		||||
#   pull: if-not-exists
 | 
			
		||||
#   commands:
 | 
			
		||||
#     - cd docs
 | 
			
		||||
#     - mkdir generated
 | 
			
		||||
#     - touch generated/changelogs.rst
 | 
			
		||||
#     - touch generated/api.rst
 | 
			
		||||
#     - sphinx-build -M html . .
 | 
			
		||||
#
 | 
			
		||||
#     - rm -rf /light_docs/*
 | 
			
		||||
#     - mv ./html/* /light_docs/
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
kind: pipeline
 | 
			
		||||
type: docker
 | 
			
		||||
name: amd64 — clang
 | 
			
		||||
trigger:
 | 
			
		||||
  branch:
 | 
			
		||||
  - main
 | 
			
		||||
 | 
			
		||||
steps:
 | 
			
		||||
- name: code coverage
 | 
			
		||||
  image: ci:latest
 | 
			
		||||
  pull: if-not-exists
 | 
			
		||||
  environment:
 | 
			
		||||
    CODECOV_TOKEN:
 | 
			
		||||
      from_secret: CODECOV_TOKEN 
 | 
			
		||||
  commands:
 | 
			
		||||
    - ./tools/ci/amd64/clang/coverage.sh
 | 
			
		||||
 | 
			
		||||
- name: leak sanitizer
 | 
			
		||||
  image: ci:latest 
 | 
			
		||||
  pull: if-not-exists
 | 
			
		||||
  commands:
 | 
			
		||||
    - ./tools/ci/amd64/clang/lsan.sh
 | 
			
		||||
 | 
			
		||||
- name: memory sanitizer
 | 
			
		||||
  image: ci:latest
 | 
			
		||||
  pull: if-not-exists
 | 
			
		||||
  commands:
 | 
			
		||||
    - ./tools/ci/amd64/clang/msan.sh
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
kind: pipeline
 | 
			
		||||
type: docker
 | 
			
		||||
name: static analysis
 | 
			
		||||
trigger:
 | 
			
		||||
  branch:
 | 
			
		||||
  - main
 | 
			
		||||
 | 
			
		||||
steps:
 | 
			
		||||
- name: clang tidy
 | 
			
		||||
  image: ci:latest 
 | 
			
		||||
  pull: if-not-exists
 | 
			
		||||
  privileged: true
 | 
			
		||||
  commands:
 | 
			
		||||
    - ./tools/ci/static_analysis/clang_tidy.sh
 | 
			
		||||
 | 
			
		||||
- name: clang format
 | 
			
		||||
  image: ci:latest 
 | 
			
		||||
  pull: if-not-exists
 | 
			
		||||
  commands:
 | 
			
		||||
    - ./tools/ci/static_analysis/clang_format.sh
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
kind: pipeline
 | 
			
		||||
type: docker 
 | 
			
		||||
name: documentation — development
 | 
			
		||||
node:
 | 
			
		||||
  environment: ryali
 | 
			
		||||
trigger:
 | 
			
		||||
  branch:
 | 
			
		||||
  - main
 | 
			
		||||
 | 
			
		||||
steps:
 | 
			
		||||
- name: build and deploy
 | 
			
		||||
  image: documentation:latest
 | 
			
		||||
  pull: if-not-exists
 | 
			
		||||
  commands:
 | 
			
		||||
    - pwd
 | 
			
		||||
    - cd docs
 | 
			
		||||
    - mkdir generated
 | 
			
		||||
    - touch generated/changelogs.rst
 | 
			
		||||
    - touch generated/api.rst
 | 
			
		||||
    - sphinx-build -M html . .
 | 
			
		||||
 | 
			
		||||
    - rm -rf /light_docs_dev/*
 | 
			
		||||
    - mv ./html/* /light_docs_dev/
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
kind: pipeline
 | 
			
		||||
type: docker
 | 
			
		||||
name: documentation — production
 | 
			
		||||
node:
 | 
			
		||||
  environment: ryali
 | 
			
		||||
trigger:
 | 
			
		||||
  event:
 | 
			
		||||
  - tag
 | 
			
		||||
 | 
			
		||||
steps:
 | 
			
		||||
- name: build and deploy
 | 
			
		||||
  image: documentation:latest
 | 
			
		||||
  pull: if-not-exists
 | 
			
		||||
  commands:
 | 
			
		||||
    - cd docs
 | 
			
		||||
    - mkdir generated
 | 
			
		||||
    - touch generated/changelogs.rst
 | 
			
		||||
    - touch generated/api.rst
 | 
			
		||||
    - sphinx-build -M html . .
 | 
			
		||||
 | 
			
		||||
    - rm -rf /light_docs/*
 | 
			
		||||
    - mv ./html/* /light_docs/
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,8 +40,16 @@ Device::~Device()
 | 
			
		|||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	vkc(vk_device_wait_idle(m_device));
 | 
			
		||||
	vk_destroy_device(m_device, nullptr);
 | 
			
		||||
	try
 | 
			
		||||
	{
 | 
			
		||||
		vkc(vk_device_wait_idle(m_device));
 | 
			
		||||
		vk_destroy_device(m_device, nullptr);
 | 
			
		||||
	}
 | 
			
		||||
	catch (const std::exception &exp)
 | 
			
		||||
	{
 | 
			
		||||
		log_err("Failed to destroy vk device:");
 | 
			
		||||
		log_err("\twhat: {}", exp.what());
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Device::initialize_logical_device()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
#include <app/system.hpp>
 | 
			
		||||
#include <renderer/backend/vk/context/instance.hpp>
 | 
			
		||||
#include <renderer/backend/vk/utils.hpp>
 | 
			
		||||
#include <vulkan/vulkan_core.h>
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
	#error "Unsupported platform (currently)"
 | 
			
		||||
| 
						 | 
				
			
			@ -194,7 +195,7 @@ void Instance::initialize_instance()
 | 
			
		|||
	const VkLayerSettingsCreateInfoEXT layer_settings_create_info = {
 | 
			
		||||
		.sType = VK_STRUCTURE_TYPE_LAYER_SETTINGS_CREATE_INFO_EXT,
 | 
			
		||||
		.settingCount = settings.size(),
 | 
			
		||||
		.pSettings = settings.data()
 | 
			
		||||
		.pSettings = settings.data(),
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	auto layers = std::vector<const char *> {
 | 
			
		||||
| 
						 | 
				
			
			@ -231,11 +232,12 @@ void Instance::initialize_instance()
 | 
			
		|||
 | 
			
		||||
void Instance::load_library()
 | 
			
		||||
{
 | 
			
		||||
	library = dlopen("libvulkan.so.1", RTLD_NOW | RTLD_LOCAL);
 | 
			
		||||
    if(!library)
 | 
			
		||||
    {
 | 
			
		||||
        library = dlopen("libvulkan.so", RTLD_NOW | RTLD_LOCAL | RTLD_NODELETE);
 | 
			
		||||
    }
 | 
			
		||||
	constexpr auto runtime_loader_flags = RTLD_NOW | RTLD_DEEPBIND | RTLD_LOCAL | RTLD_NODELETE;
 | 
			
		||||
	library = dlopen("libvulkan.so.1", runtime_loader_flags);
 | 
			
		||||
	if (!library)
 | 
			
		||||
	{
 | 
			
		||||
		library = dlopen("libvulkan.so", runtime_loader_flags);
 | 
			
		||||
	}
 | 
			
		||||
	ensure(library, "Failed to dlopen vulkan library");
 | 
			
		||||
 | 
			
		||||
	// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,49 +42,50 @@ Suite raii = "raii"_suite = [] {
 | 
			
		|||
		// expect_not_nullptr(vk_destroy_surface_khr);
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	Case { "post load device functions state is correct" } = [] {
 | 
			
		||||
		using namespace renderer::vk;
 | 
			
		||||
		expect_not_nullptr(Instance::get());
 | 
			
		||||
 | 
			
		||||
		expect_not_nullptr(vk_get_device_queue);
 | 
			
		||||
		expect_not_nullptr(vk_create_command_pool);
 | 
			
		||||
		expect_not_nullptr(vk_destroy_command_pool);
 | 
			
		||||
		expect_not_nullptr(vk_allocate_command_buffers);
 | 
			
		||||
		expect_not_nullptr(vk_free_command_buffers);
 | 
			
		||||
		expect_not_nullptr(vk_begin_command_buffer);
 | 
			
		||||
		expect_not_nullptr(vk_end_command_buffer);
 | 
			
		||||
		expect_not_nullptr(vk_cmd_pipeline_barrier);
 | 
			
		||||
		expect_not_nullptr(vk_queue_submit);
 | 
			
		||||
		expect_not_nullptr(vk_queue_wait_idle);
 | 
			
		||||
		expect_not_nullptr(vk_device_wait_idle);
 | 
			
		||||
		expect_not_nullptr(vk_create_fence);
 | 
			
		||||
		expect_not_nullptr(vk_destroy_fence);
 | 
			
		||||
		expect_not_nullptr(vk_wait_for_fences);
 | 
			
		||||
		expect_not_nullptr(vk_reset_fences);
 | 
			
		||||
		expect_not_nullptr(vk_create_semaphore);
 | 
			
		||||
		expect_not_nullptr(vk_destroy_semaphore);
 | 
			
		||||
		expect_not_nullptr(vk_create_swapchain_khr);
 | 
			
		||||
		expect_not_nullptr(vk_destroy_swapchain_khr);
 | 
			
		||||
		expect_not_nullptr(vk_get_swapchain_images_khr);
 | 
			
		||||
		expect_not_nullptr(vk_acquire_next_image_khr);
 | 
			
		||||
		expect_not_nullptr(vk_queue_present_khr);
 | 
			
		||||
		expect_not_nullptr(vk_create_image_view);
 | 
			
		||||
		expect_not_nullptr(vk_destroy_image_view);
 | 
			
		||||
		expect_not_nullptr(vk_create_render_pass);
 | 
			
		||||
		expect_not_nullptr(vk_destroy_render_pass);
 | 
			
		||||
		expect_not_nullptr(vk_create_frame_buffer);
 | 
			
		||||
		expect_not_nullptr(vk_destroy_frame_buffer);
 | 
			
		||||
		expect_not_nullptr(vk_create_shader_module);
 | 
			
		||||
		expect_not_nullptr(vk_destroy_shader_module);
 | 
			
		||||
		expect_not_nullptr(vk_create_pipeline_layout);
 | 
			
		||||
		expect_not_nullptr(vk_destroy_pipeline_layout);
 | 
			
		||||
		expect_not_nullptr(vk_create_graphics_pipelines);
 | 
			
		||||
		expect_not_nullptr(vk_destroy_pipeline);
 | 
			
		||||
		expect_not_nullptr(vk_cmd_begin_render_pass);
 | 
			
		||||
		expect_not_nullptr(vk_cmd_end_render_pass);
 | 
			
		||||
		expect_not_nullptr(vk_cmd_bind_pipeline);
 | 
			
		||||
		expect_not_nullptr(vk_cmd_draw);
 | 
			
		||||
		expect_not_nullptr(vk_cmd_set_viewport);
 | 
			
		||||
		expect_not_nullptr(vk_cmd_set_scissors);
 | 
			
		||||
	};
 | 
			
		||||
	// TODO(Light): move device function symbols to device.cpp
 | 
			
		||||
	// Case { "post load device functions state is correct" } = [] {
 | 
			
		||||
	// 	using namespace renderer::vk;
 | 
			
		||||
	// 	expect_not_nullptr(Instance::get());
 | 
			
		||||
	//
 | 
			
		||||
	// 	expect_not_nullptr(vk_get_device_queue);
 | 
			
		||||
	// 	expect_not_nullptr(vk_create_command_pool);
 | 
			
		||||
	// 	expect_not_nullptr(vk_destroy_command_pool);
 | 
			
		||||
	// 	expect_not_nullptr(vk_allocate_command_buffers);
 | 
			
		||||
	// 	expect_not_nullptr(vk_free_command_buffers);
 | 
			
		||||
	// 	expect_not_nullptr(vk_begin_command_buffer);
 | 
			
		||||
	// 	expect_not_nullptr(vk_end_command_buffer);
 | 
			
		||||
	// 	expect_not_nullptr(vk_cmd_pipeline_barrier);
 | 
			
		||||
	// 	expect_not_nullptr(vk_queue_submit);
 | 
			
		||||
	// 	expect_not_nullptr(vk_queue_wait_idle);
 | 
			
		||||
	// 	expect_not_nullptr(vk_device_wait_idle);
 | 
			
		||||
	// 	expect_not_nullptr(vk_create_fence);
 | 
			
		||||
	// 	expect_not_nullptr(vk_destroy_fence);
 | 
			
		||||
	// 	expect_not_nullptr(vk_wait_for_fences);
 | 
			
		||||
	// 	expect_not_nullptr(vk_reset_fences);
 | 
			
		||||
	// 	expect_not_nullptr(vk_create_semaphore);
 | 
			
		||||
	// 	expect_not_nullptr(vk_destroy_semaphore);
 | 
			
		||||
	// 	expect_not_nullptr(vk_create_swapchain_khr);
 | 
			
		||||
	// 	expect_not_nullptr(vk_destroy_swapchain_khr);
 | 
			
		||||
	// 	expect_not_nullptr(vk_get_swapchain_images_khr);
 | 
			
		||||
	// 	expect_not_nullptr(vk_acquire_next_image_khr);
 | 
			
		||||
	// 	expect_not_nullptr(vk_queue_present_khr);
 | 
			
		||||
	// 	expect_not_nullptr(vk_create_image_view);
 | 
			
		||||
	// 	expect_not_nullptr(vk_destroy_image_view);
 | 
			
		||||
	// 	expect_not_nullptr(vk_create_render_pass);
 | 
			
		||||
	// 	expect_not_nullptr(vk_destroy_render_pass);
 | 
			
		||||
	// 	expect_not_nullptr(vk_create_frame_buffer);
 | 
			
		||||
	// 	expect_not_nullptr(vk_destroy_frame_buffer);
 | 
			
		||||
	// 	expect_not_nullptr(vk_create_shader_module);
 | 
			
		||||
	// 	expect_not_nullptr(vk_destroy_shader_module);
 | 
			
		||||
	// 	expect_not_nullptr(vk_create_pipeline_layout);
 | 
			
		||||
	// 	expect_not_nullptr(vk_destroy_pipeline_layout);
 | 
			
		||||
	// 	expect_not_nullptr(vk_create_graphics_pipelines);
 | 
			
		||||
	// 	expect_not_nullptr(vk_destroy_pipeline);
 | 
			
		||||
	// 	expect_not_nullptr(vk_cmd_begin_render_pass);
 | 
			
		||||
	// 	expect_not_nullptr(vk_cmd_end_render_pass);
 | 
			
		||||
	// 	expect_not_nullptr(vk_cmd_bind_pipeline);
 | 
			
		||||
	// 	expect_not_nullptr(vk_cmd_draw);
 | 
			
		||||
	// 	expect_not_nullptr(vk_cmd_set_viewport);
 | 
			
		||||
	// 	expect_not_nullptr(vk_cmd_set_scissors);
 | 
			
		||||
	// };
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -76,6 +76,7 @@ Swapchain::Swapchain(ISurface *surface, IGpu *gpu, IDevice *device)
 | 
			
		|||
		m_device->name(image, "swapchain image {}", idx++);
 | 
			
		||||
		m_device->name(view, "swapchain image view {}", idx++);
 | 
			
		||||
	}
 | 
			
		||||
	m_device->wait_idle();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Swapchain::~Swapchain()
 | 
			
		||||
| 
						 | 
				
			
			@ -90,6 +91,7 @@ Swapchain::~Swapchain()
 | 
			
		|||
		m_device->wait_idle();
 | 
			
		||||
		m_device->destroy_image_views(m_image_views);
 | 
			
		||||
		m_device->destroy_swapchain(m_swapchain);
 | 
			
		||||
		m_device->wait_idle();
 | 
			
		||||
	}
 | 
			
		||||
	catch (const std::exception &exp)
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,7 @@ namespace lt::renderer::vk {
 | 
			
		|||
Messenger::Messenger(IInstance *instance, CreateInfo info)
 | 
			
		||||
    : m_instance(static_cast<Instance *>(instance))
 | 
			
		||||
    , m_user_data(std::move(info.user_data))
 | 
			
		||||
    , m_user_callback(std::move(info.callback))
 | 
			
		||||
    , m_debug_messenger(
 | 
			
		||||
          m_instance,
 | 
			
		||||
          VkDebugUtilsMessengerCreateInfoEXT {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,7 +10,15 @@ Pass::Pass(
 | 
			
		|||
    const lt::assets::ShaderAsset &vertex_shader,
 | 
			
		||||
    const lt::assets::ShaderAsset &fragment_shader
 | 
			
		||||
)
 | 
			
		||||
    : m_device(static_cast<Device *>(device))
 | 
			
		||||
    : m_device(static_cast<Device *>(device)), m_layout(m_device->create_pipeline_layout(
 | 
			
		||||
	    VkPipelineLayoutCreateInfo {
 | 
			
		||||
	        .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
 | 
			
		||||
	        .setLayoutCount = 0u,
 | 
			
		||||
	        .pSetLayouts = nullptr,
 | 
			
		||||
	        .pushConstantRangeCount = 0u,
 | 
			
		||||
	        .pPushConstantRanges = nullptr,
 | 
			
		||||
	    }
 | 
			
		||||
	))
 | 
			
		||||
{
 | 
			
		||||
	auto *vertex_module = create_module(
 | 
			
		||||
	    vertex_shader.unpack(lt::assets::ShaderAsset::BlobTag::code)
 | 
			
		||||
| 
						 | 
				
			
			@ -103,15 +111,7 @@ Pass::Pass(
 | 
			
		|||
		.blendConstants = { 0.0f, 0.0, 0.0, 0.0 },
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	m_layout = m_device->create_pipeline_layout(
 | 
			
		||||
	    VkPipelineLayoutCreateInfo {
 | 
			
		||||
	        .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
 | 
			
		||||
	        .setLayoutCount = 0u,
 | 
			
		||||
	        .pSetLayouts = nullptr,
 | 
			
		||||
	        .pushConstantRangeCount = 0u,
 | 
			
		||||
	        .pPushConstantRanges = nullptr,
 | 
			
		||||
	    }
 | 
			
		||||
	);
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
	auto attachment_description = VkAttachmentDescription {
 | 
			
		||||
		.format = static_cast<Swapchain *>(swapchain)->get_format(),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,6 @@ class IInstance
 | 
			
		|||
{
 | 
			
		||||
public:
 | 
			
		||||
	[[nodiscard]] static auto get(Api target_api) -> IInstance *;
 | 
			
		||||
 | 
			
		||||
	IInstance() = default;
 | 
			
		||||
 | 
			
		||||
	virtual ~IInstance() = default;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,6 @@
 | 
			
		|||
 | 
			
		||||
using ::lt::ecs::EntityId;
 | 
			
		||||
using ::lt::ecs::Registry;
 | 
			
		||||
using ::lt::surface::SurfaceComponent;
 | 
			
		||||
 | 
			
		||||
Suite raii = "surface"_suite = [] {
 | 
			
		||||
	Case { "happy path won't throw" } = [&] {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,10 @@
 | 
			
		|||
#include <assets/shader.hpp>
 | 
			
		||||
#include <renderer/frontend/messenger.hpp>
 | 
			
		||||
#include <renderer/frontend/renderer/pass.hpp>
 | 
			
		||||
#include <renderer/test/utils.hpp>
 | 
			
		||||
 | 
			
		||||
using ::lt::renderer::IMessenger;
 | 
			
		||||
 | 
			
		||||
Suite raii = "pass_raii"_suite = [] {
 | 
			
		||||
	Case { "happy path won't throw" } = [] {
 | 
			
		||||
		auto fixture = Fixture_RendererSystem {};
 | 
			
		||||
| 
						 | 
				
			
			@ -14,6 +17,9 @@ Suite raii = "pass_raii"_suite = [] {
 | 
			
		|||
		    lt::assets::ShaderAsset { "./data/test_assets/triangle.vert.asset" },
 | 
			
		||||
		    lt::assets::ShaderAsset { "./data/test_assets/triangle.frag.asset" }
 | 
			
		||||
		);
 | 
			
		||||
 | 
			
		||||
		expect_false(fixture.has_any_messages_of(IMessenger ::MessageSeverity::error));
 | 
			
		||||
		expect_false(fixture.has_any_messages_of(IMessenger ::MessageSeverity::warning));
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	Case { "unhappy path throws" } = [] {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,8 +47,7 @@ System::System(CreateInfo info)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
System::~System()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
= default;
 | 
			
		||||
 | 
			
		||||
void System::on_register()
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -148,7 +148,58 @@ public:
 | 
			
		|||
		);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	[[nodiscard]] auto has_any_messages() const -> bool
 | 
			
		||||
	{
 | 
			
		||||
		return m_user_data->m_has_any_messages;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	[[nodiscard]] auto has_any_messages_of(
 | 
			
		||||
	    lt::renderer::IMessenger ::MessageSeverity severity
 | 
			
		||||
	) const -> uint32_t
 | 
			
		||||
	{
 | 
			
		||||
		return m_user_data->m_severity_counter.contains(severity);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	static void messenger_callback(
 | 
			
		||||
	    lt::renderer::IMessenger::MessageSeverity severity,
 | 
			
		||||
	    lt::renderer::IMessenger::MessageType type,
 | 
			
		||||
	    const lt::renderer::IMessenger::MessageData &data,
 | 
			
		||||
	    std::any &user_data
 | 
			
		||||
	)
 | 
			
		||||
	{
 | 
			
		||||
		// I know this makes the tests too verbose...
 | 
			
		||||
		// but makes it easier to figure out what the problem is when things fail on ci
 | 
			
		||||
		log_trc("vulkan: {}", data.message);
 | 
			
		||||
		std::ignore = data;
 | 
			
		||||
		std::ignore = type;
 | 
			
		||||
 | 
			
		||||
		auto *fixture = std::any_cast<UserData *>(user_data);
 | 
			
		||||
		fixture->m_has_any_messages = true;
 | 
			
		||||
		++fixture->m_severity_counter[severity];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	struct UserData
 | 
			
		||||
	{
 | 
			
		||||
		std::unordered_map<lt::renderer::IMessenger::MessageSeverity, uint32_t> m_severity_counter;
 | 
			
		||||
 | 
			
		||||
		bool m_has_any_messages {};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	lt::memory::Scope<UserData> m_user_data = lt::memory::create_scope<UserData>();
 | 
			
		||||
 | 
			
		||||
	lt::memory::Scope<lt::renderer::IMessenger> m_messenger = lt::renderer::IMessenger::create(
 | 
			
		||||
	    constants::api,
 | 
			
		||||
	    lt::renderer::IInstance::get(constants::api),
 | 
			
		||||
	    lt::renderer::IMessenger ::CreateInfo {
 | 
			
		||||
	        .severities = lt::renderer::IMessenger ::MessageSeverity::all,
 | 
			
		||||
	        .types = lt::renderer::IMessenger ::MessageType::all,
 | 
			
		||||
	        .callback = &messenger_callback,
 | 
			
		||||
	        .user_data = m_user_data.get(),
 | 
			
		||||
	    }
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
	lt::memory::Scope<lt::renderer::IDevice> m_device {
 | 
			
		||||
		lt::renderer::IDevice::create(constants::api, gpu(), surface())
 | 
			
		||||
	};
 | 
			
		||||
| 
						 | 
				
			
			@ -188,6 +239,10 @@ private:
 | 
			
		|||
	    std::any &user_data
 | 
			
		||||
	)
 | 
			
		||||
	{
 | 
			
		||||
		// I know this makes the tests too verbose...
 | 
			
		||||
		// but makes it easier to figure out what the problem is when things fail on ci
 | 
			
		||||
		log_trc("vulkan: {}", data.message);
 | 
			
		||||
 | 
			
		||||
		std::ignore = data;
 | 
			
		||||
		std::ignore = type;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,7 +41,7 @@ public:
 | 
			
		|||
	using Callback_T = std::function<void(
 | 
			
		||||
	    MessageSeverity message_severity,
 | 
			
		||||
	    MessageType message_type,
 | 
			
		||||
	    MessageData data,
 | 
			
		||||
	    const MessageData &data,
 | 
			
		||||
	    std::any &user_data
 | 
			
		||||
	)>;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,6 +17,7 @@ cmake . \
 | 
			
		|||
-DCMAKE_BUILD_TYPE=Debug \
 | 
			
		||||
-DCMAKE_CXX_FLAGS=" \
 | 
			
		||||
-fsanitize=leak \
 | 
			
		||||
-fno-common \
 | 
			
		||||
-g \
 | 
			
		||||
-fno-omit-frame-pointer \
 | 
			
		||||
-std=c++23 \
 | 
			
		||||
| 
						 | 
				
			
			@ -28,11 +29,11 @@ cmake . \
 | 
			
		|||
-lc++ \
 | 
			
		||||
-lc++abi \
 | 
			
		||||
-Wl,-rpath,/libcxx_lsan/lib" \
 | 
			
		||||
&& cmake --build ./build -j`nproc`
 | 
			
		||||
 | 
			
		||||
export LSAN_OPTIONS="suppressions=$(git rev-parse --show-toplevel)/tools/ci/amd64/clang/lsan.supp"
 | 
			
		||||
&& cmake --build ./build --target='renderer_tests' -j`nproc`
 | 
			
		||||
 | 
			
		||||
export LSAN_OPTIONS="suppressions=$(git rev-parse --show-toplevel)/tools/ci/amd64/clang/lsan.supp:fast_unwind_on_malloc=0:verbosity=1:report_objects=1"
 | 
			
		||||
export LSAN_SYMBOLIZER_PATH="$(which llvm-symbolizer)"
 | 
			
		||||
for test in $(find ./build -type f -name '*_tests' -executable); do
 | 
			
		||||
  echo "Running $test"
 | 
			
		||||
  "$test"
 | 
			
		||||
    echo "Running $test"
 | 
			
		||||
    "$test"
 | 
			
		||||
done
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,4 @@
 | 
			
		|||
leak:libX11
 | 
			
		||||
leak:_dlopen
 | 
			
		||||
leak:_dlclose
 | 
			
		||||
leak:lt::renderer::vk::Device::destroy_swapchain
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue