Compare commits
	
		
			1 commit
		
	
	
		
			main
			...
			feat/test_
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 4ce413a1d7 | 
					 80 changed files with 1069 additions and 1592 deletions
				
			
		
							
								
								
									
										5
									
								
								.clangd
									
										
									
									
									
								
							
							
						
						
									
										5
									
								
								.clangd
									
										
									
									
									
								
							| 
						 | 
					@ -1,5 +0,0 @@
 | 
				
			||||||
CompileFlags:
 | 
					 | 
				
			||||||
  DriverMode: cl
 | 
					 | 
				
			||||||
  Add:
 | 
					 | 
				
			||||||
    - /EHsc
 | 
					 | 
				
			||||||
    - /std:c++latest
 | 
					 | 
				
			||||||
							
								
								
									
										286
									
								
								.drone.yml
									
										
									
									
									
								
							
							
						
						
									
										286
									
								
								.drone.yml
									
										
									
									
									
								
							| 
						 | 
					@ -1,42 +1,42 @@
 | 
				
			||||||
---
 | 
					# ---
 | 
				
			||||||
kind: pipeline
 | 
					# kind: pipeline
 | 
				
			||||||
type: exec
 | 
					# type: exec
 | 
				
			||||||
name: amd64 — msvc
 | 
					# name: amd64 — msvc
 | 
				
			||||||
trigger:
 | 
					# trigger:
 | 
				
			||||||
  branch:
 | 
					#   branch:
 | 
				
			||||||
  - main
 | 
					#   - main
 | 
				
			||||||
platform:
 | 
					# platform:
 | 
				
			||||||
  os: windows
 | 
					#   os: windows
 | 
				
			||||||
  arch: amd64
 | 
					#   arch: amd64
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
steps:
 | 
					# steps:
 | 
				
			||||||
- name: unit tests
 | 
					# - name: unit tests
 | 
				
			||||||
  shell: powershell
 | 
					#   shell: powershell
 | 
				
			||||||
  commands: 
 | 
					#   commands: 
 | 
				
			||||||
    - ./tools/ci/amd64/msvc/unit_tests.ps1
 | 
					#     - ./tools/ci/amd64/msvc/unit_tests.ps1
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
---
 | 
					# ---
 | 
				
			||||||
kind: pipeline
 | 
					# kind: pipeline
 | 
				
			||||||
type: docker
 | 
					# type: docker
 | 
				
			||||||
name: amd64 — gcc
 | 
					# name: amd64 — gcc
 | 
				
			||||||
trigger:
 | 
					# trigger:
 | 
				
			||||||
  branch:
 | 
					#   branch:
 | 
				
			||||||
  - main
 | 
					#   - main
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
steps:
 | 
					# steps:
 | 
				
			||||||
- name: unit tests
 | 
					# - name: unit tests
 | 
				
			||||||
  image: ci:latest
 | 
					#   image: ci:latest
 | 
				
			||||||
  pull: if-not-exists
 | 
					#   pull: if-not-exists
 | 
				
			||||||
  commands:
 | 
					#   commands:
 | 
				
			||||||
    - ./tools/ci/amd64/gcc/unit_tests.sh
 | 
					#     - ./tools/ci/amd64/gcc/unit_tests.sh
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
- name: valgrind
 | 
					# - name: valgrind
 | 
				
			||||||
  image: ci:latest
 | 
					#   image: ci:latest
 | 
				
			||||||
  pull: if-not-exists
 | 
					#   pull: if-not-exists
 | 
				
			||||||
  commands:
 | 
					#   commands:
 | 
				
			||||||
    - ./tools/ci/amd64/gcc/valgrind.sh
 | 
					#     - ./tools/ci/amd64/gcc/valgrind.sh
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
---
 | 
					# ---
 | 
				
			||||||
kind: pipeline
 | 
					kind: pipeline
 | 
				
			||||||
type: docker
 | 
					type: docker
 | 
				
			||||||
name: amd64 — clang
 | 
					name: amd64 — clang
 | 
				
			||||||
| 
						 | 
					@ -45,110 +45,114 @@ trigger:
 | 
				
			||||||
  - main
 | 
					  - main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
steps:
 | 
					steps:
 | 
				
			||||||
- name: code coverage
 | 
					# - name: code coverage
 | 
				
			||||||
  image: ci:latest
 | 
					#   image: ci:latest
 | 
				
			||||||
  pull: if-not-exists
 | 
					#   pull: if-not-exists
 | 
				
			||||||
  environment:
 | 
					#   environment:
 | 
				
			||||||
    CODECOV_TOKEN:
 | 
					#     CODECOV_TOKEN:
 | 
				
			||||||
      from_secret: CODECOV_TOKEN 
 | 
					#       from_secret: CODECOV_TOKEN 
 | 
				
			||||||
  commands:
 | 
					#   commands:
 | 
				
			||||||
    - ./tools/ci/amd64/clang/coverage.sh
 | 
					#     - ./tools/ci/amd64/clang/coverage.sh
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
- name: leak sanitizer
 | 
					# - name: leak sanitizer
 | 
				
			||||||
  image: ci:latest
 | 
					#   image: ci:latest
 | 
				
			||||||
  pull: if-not-exists
 | 
					#   pull: if-not-exists
 | 
				
			||||||
  commands:
 | 
					#   commands:
 | 
				
			||||||
    - ./tools/ci/amd64/clang/lsan.sh
 | 
					#     - ./tools/ci/amd64/clang/lsan.sh
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
- name: memory sanitizer
 | 
					- name: memory sanitizer
 | 
				
			||||||
  image: ci:latest
 | 
					  image: ci:latest
 | 
				
			||||||
  pull: if-not-exists
 | 
					  pull: if-not-exists
 | 
				
			||||||
  commands:
 | 
					  commands:
 | 
				
			||||||
    - ./tools/ci/amd64/clang/msan.sh
 | 
					    - ./tools/ci/amd64/clang/msan.sh
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
---
 | 
					# ---
 | 
				
			||||||
kind: pipeline
 | 
					# kind: pipeline
 | 
				
			||||||
type: docker
 | 
					# type: docker
 | 
				
			||||||
name: static analysis
 | 
					# name: static analysis
 | 
				
			||||||
trigger:
 | 
					# trigger:
 | 
				
			||||||
  branch:
 | 
					#   branch:
 | 
				
			||||||
  - main
 | 
					#   - main
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
steps:
 | 
					# steps:
 | 
				
			||||||
- name: clang tidy
 | 
					# - name: clang tidy
 | 
				
			||||||
  image: ci:latest
 | 
					#   image: ci:latest
 | 
				
			||||||
  pull: if-not-exists
 | 
					#   pull: if-not-exists
 | 
				
			||||||
  privileged: true
 | 
					#   privileged: true
 | 
				
			||||||
  commands:
 | 
					#   commands:
 | 
				
			||||||
    - ./tools/ci/static_analysis/clang_tidy.sh
 | 
					#     - ./tools/ci/static_analysis/clang_tidy.sh
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
- name: shell check
 | 
					# - name: shell check
 | 
				
			||||||
  image: ci:latest
 | 
					#   image: ci:latest
 | 
				
			||||||
  pull: if-not-exists
 | 
					#   pull: if-not-exists
 | 
				
			||||||
  commands:
 | 
					#   commands:
 | 
				
			||||||
    - ./tools/ci/static_analysis/shell_check.sh
 | 
					#     - ./tools/ci/static_analysis/shell_check.sh
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
- name: clang format
 | 
					# - name: clang format
 | 
				
			||||||
  image: ci:latest
 | 
					#   image: ci:latest
 | 
				
			||||||
  pull: if-not-exists
 | 
					#   pull: if-not-exists
 | 
				
			||||||
  commands:
 | 
					#   commands:
 | 
				
			||||||
    - ./tools/ci/static_analysis/clang_format.sh
 | 
					#     - ./tools/ci/static_analysis/clang_format.sh
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
- name: cmake format
 | 
					# - name: cmake format
 | 
				
			||||||
  image: ci:latest
 | 
					#   image: ci:latest
 | 
				
			||||||
  pull: if-not-exists
 | 
					#   pull: if-not-exists
 | 
				
			||||||
  commands:
 | 
					#   commands:
 | 
				
			||||||
    - ./tools/ci/static_analysis/cmake_format.sh
 | 
					#     - ./tools/ci/static_analysis/cmake_format.sh
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
- name: shell format
 | 
					# - name: shell format
 | 
				
			||||||
  image: ci:latest
 | 
					#   image: ci:latest
 | 
				
			||||||
  pull: if-not-exists
 | 
					#   pull: if-not-exists
 | 
				
			||||||
  commands:
 | 
					#   commands:
 | 
				
			||||||
    - ./tools/ci/static_analysis/shell_format.sh
 | 
					#     - ./tools/ci/static_analysis/shell_format.sh
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
---
 | 
					# ---
 | 
				
			||||||
kind: pipeline
 | 
					# kind: pipeline
 | 
				
			||||||
type: docker 
 | 
					# type: docker 
 | 
				
			||||||
name: documentation — development
 | 
					# name: documentation — development
 | 
				
			||||||
node:
 | 
					# node:
 | 
				
			||||||
  environment: ryali
 | 
					#   environment: ryali
 | 
				
			||||||
trigger:
 | 
					# trigger:
 | 
				
			||||||
  branch:
 | 
					#   branch:
 | 
				
			||||||
  - main
 | 
					#   - main
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
steps:
 | 
					# steps:
 | 
				
			||||||
- name: build and deploy
 | 
					# - name: build and deploy
 | 
				
			||||||
  image: documentation:latest
 | 
					#   image: documentation:latest
 | 
				
			||||||
  pull: if-not-exists
 | 
					#   pull: if-not-exists
 | 
				
			||||||
  commands:
 | 
					#   commands:
 | 
				
			||||||
    - cd docs
 | 
					#     - pwd
 | 
				
			||||||
    - sphinx-build -M html . .
 | 
					#     - cd docs
 | 
				
			||||||
 | 
					#     - mkdir generated
 | 
				
			||||||
    - rm -rf /light_docs_dev/*
 | 
					#     - touch generated/changelogs.rst
 | 
				
			||||||
    - mv ./html/* /light_docs_dev/
 | 
					#     - touch generated/api.rst
 | 
				
			||||||
 | 
					#     - sphinx-build -M html . .
 | 
				
			||||||
---
 | 
					#
 | 
				
			||||||
 | 
					#     - rm -rf /light_docs_dev/*
 | 
				
			||||||
kind: pipeline
 | 
					#     - mv ./html/* /light_docs_dev/
 | 
				
			||||||
type: docker
 | 
					#
 | 
				
			||||||
name: documentation — production
 | 
					# ---
 | 
				
			||||||
node:
 | 
					#
 | 
				
			||||||
  environment: ryali
 | 
					# kind: pipeline
 | 
				
			||||||
trigger:
 | 
					# type: docker
 | 
				
			||||||
  event:
 | 
					# name: documentation — production
 | 
				
			||||||
  - tag
 | 
					# node:
 | 
				
			||||||
 | 
					#   environment: ryali
 | 
				
			||||||
steps:
 | 
					# trigger:
 | 
				
			||||||
- name: build and deploy
 | 
					#   event:
 | 
				
			||||||
  image: documentation:latest
 | 
					#   - tag
 | 
				
			||||||
  pull: if-not-exists
 | 
					#
 | 
				
			||||||
  commands:
 | 
					# steps:
 | 
				
			||||||
    - cd docs
 | 
					# - name: build and deploy
 | 
				
			||||||
    - mkdir generated
 | 
					#   image: documentation:latest
 | 
				
			||||||
    - touch generated/changelogs.rst
 | 
					#   pull: if-not-exists
 | 
				
			||||||
    - touch generated/api.rst
 | 
					#   commands:
 | 
				
			||||||
    - sphinx-build -M html . .
 | 
					#     - cd docs
 | 
				
			||||||
 | 
					#     - mkdir generated
 | 
				
			||||||
    - rm -rf /light_docs/*
 | 
					#     - touch generated/changelogs.rst
 | 
				
			||||||
    - mv ./html/* /light_docs/
 | 
					#     - touch generated/api.rst
 | 
				
			||||||
 | 
					#     - sphinx-build -M html . .
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#     - rm -rf /light_docs/*
 | 
				
			||||||
 | 
					#     - mv ./html/* /light_docs/
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										128
									
								
								CODE_OF_CONDUCT.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								CODE_OF_CONDUCT.md
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,128 @@
 | 
				
			||||||
 | 
					# Contributor Covenant Code of Conduct
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Our Pledge
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					We as members, contributors, and leaders pledge to make participation in our
 | 
				
			||||||
 | 
					community a harassment-free experience for everyone, regardless of age, body
 | 
				
			||||||
 | 
					size, visible or invisible disability, ethnicity, sex characteristics, gender
 | 
				
			||||||
 | 
					identity and expression, level of experience, education, socio-economic status,
 | 
				
			||||||
 | 
					nationality, personal appearance, race, religion, or sexual identity
 | 
				
			||||||
 | 
					and orientation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					We pledge to act and interact in ways that contribute to an open, welcoming,
 | 
				
			||||||
 | 
					diverse, inclusive, and healthy community.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Our Standards
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Examples of behavior that contributes to a positive environment for our
 | 
				
			||||||
 | 
					community include:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* Demonstrating empathy and kindness toward other people
 | 
				
			||||||
 | 
					* Being respectful of differing opinions, viewpoints, and experiences
 | 
				
			||||||
 | 
					* Giving and gracefully accepting constructive feedback
 | 
				
			||||||
 | 
					* Accepting responsibility and apologizing to those affected by our mistakes,
 | 
				
			||||||
 | 
					  and learning from the experience
 | 
				
			||||||
 | 
					* Focusing on what is best not just for us as individuals, but for the
 | 
				
			||||||
 | 
					  overall community
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Examples of unacceptable behavior include:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* The use of sexualized language or imagery, and sexual attention or
 | 
				
			||||||
 | 
					  advances of any kind
 | 
				
			||||||
 | 
					* Trolling, insulting or derogatory comments, and personal or political attacks
 | 
				
			||||||
 | 
					* Public or private harassment
 | 
				
			||||||
 | 
					* Publishing others' private information, such as a physical or email
 | 
				
			||||||
 | 
					  address, without their explicit permission
 | 
				
			||||||
 | 
					* Other conduct which could reasonably be considered inappropriate in a
 | 
				
			||||||
 | 
					  professional setting
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Enforcement Responsibilities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Community leaders are responsible for clarifying and enforcing our standards of
 | 
				
			||||||
 | 
					acceptable behavior and will take appropriate and fair corrective action in
 | 
				
			||||||
 | 
					response to any behavior that they deem inappropriate, threatening, offensive,
 | 
				
			||||||
 | 
					or harmful.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Community leaders have the right and responsibility to remove, edit, or reject
 | 
				
			||||||
 | 
					comments, commits, code, wiki edits, issues, and other contributions that are
 | 
				
			||||||
 | 
					not aligned to this Code of Conduct, and will communicate reasons for moderation
 | 
				
			||||||
 | 
					decisions when appropriate.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Scope
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This Code of Conduct applies within all community spaces, and also applies when
 | 
				
			||||||
 | 
					an individual is officially representing the community in public spaces.
 | 
				
			||||||
 | 
					Examples of representing our community include using an official e-mail address,
 | 
				
			||||||
 | 
					posting via an official social media account, or acting as an appointed
 | 
				
			||||||
 | 
					representative at an online or offline event.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Enforcement
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Instances of abusive, harassing, or otherwise unacceptable behavior may be
 | 
				
			||||||
 | 
					reported to the community leaders responsible for enforcement at
 | 
				
			||||||
 | 
					Discord: Light7734#4652.
 | 
				
			||||||
 | 
					All complaints will be reviewed and investigated promptly and fairly.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					All community leaders are obligated to respect the privacy and security of the
 | 
				
			||||||
 | 
					reporter of any incident.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Enforcement Guidelines
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Community leaders will follow these Community Impact Guidelines in determining
 | 
				
			||||||
 | 
					the consequences for any action they deem in violation of this Code of Conduct:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 1. Correction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Community Impact**: Use of inappropriate language or other behavior deemed
 | 
				
			||||||
 | 
					unprofessional or unwelcome in the community.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Consequence**: A private, written warning from community leaders, providing
 | 
				
			||||||
 | 
					clarity around the nature of the violation and an explanation of why the
 | 
				
			||||||
 | 
					behavior was inappropriate. A public apology may be requested.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 2. Warning
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Community Impact**: A violation through a single incident or series
 | 
				
			||||||
 | 
					of actions.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Consequence**: A warning with consequences for continued behavior. No
 | 
				
			||||||
 | 
					interaction with the people involved, including unsolicited interaction with
 | 
				
			||||||
 | 
					those enforcing the Code of Conduct, for a specified period of time. This
 | 
				
			||||||
 | 
					includes avoiding interactions in community spaces as well as external channels
 | 
				
			||||||
 | 
					like social media. Violating these terms may lead to a temporary or
 | 
				
			||||||
 | 
					permanent ban.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 3. Temporary Ban
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Community Impact**: A serious violation of community standards, including
 | 
				
			||||||
 | 
					sustained inappropriate behavior.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Consequence**: A temporary ban from any sort of interaction or public
 | 
				
			||||||
 | 
					communication with the community for a specified period of time. No public or
 | 
				
			||||||
 | 
					private interaction with the people involved, including unsolicited interaction
 | 
				
			||||||
 | 
					with those enforcing the Code of Conduct, is allowed during this period.
 | 
				
			||||||
 | 
					Violating these terms may lead to a permanent ban.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### 4. Permanent Ban
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Community Impact**: Demonstrating a pattern of violation of community
 | 
				
			||||||
 | 
					standards, including sustained inappropriate behavior,  harassment of an
 | 
				
			||||||
 | 
					individual, or aggression toward or disparagement of classes of individuals.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Consequence**: A permanent ban from any sort of public interaction within
 | 
				
			||||||
 | 
					the community.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Attribution
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This Code of Conduct is adapted from the [Contributor Covenant][homepage],
 | 
				
			||||||
 | 
					version 2.0, available at
 | 
				
			||||||
 | 
					https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Community Impact Guidelines were inspired by [Mozilla's code of conduct
 | 
				
			||||||
 | 
					enforcement ladder](https://github.com/mozilla/diversity).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[homepage]: https://www.contributor-covenant.org
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For answers to common questions about this code of conduct, see the FAQ at
 | 
				
			||||||
 | 
					https://www.contributor-covenant.org/faq. Translations are available at
 | 
				
			||||||
 | 
					https://www.contributor-covenant.org/translations.
 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							| 
						 | 
					@ -1,26 +1,21 @@
 | 
				
			||||||
#version 450 core
 | 
					#version 450 core
 | 
				
			||||||
 | 
					
 | 
				
			||||||
layout(push_constant ) uniform pc {
 | 
					vec2 positions[3] = vec2[](
 | 
				
			||||||
 mat4 view_projection;
 | 
					    vec2(0.0, -0.5),
 | 
				
			||||||
};
 | 
					    vec2(0.5, 0.5),
 | 
				
			||||||
 | 
					    vec2(-0.5, 0.5)
 | 
				
			||||||
vec3 positions[3] = vec3[](
 | 
					 | 
				
			||||||
    vec3(0.0, -0.5, 0.5),
 | 
					 | 
				
			||||||
    vec3(0.5, 0.5, 0.5),
 | 
					 | 
				
			||||||
    vec3(-0.5, 0.5, 0.5)
 | 
					 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vec3 colors[3] = vec3[](
 | 
					vec3 colors[3] = vec3[](
 | 
				
			||||||
    vec3(0.0, 0.0, 0.0),
 | 
					    vec3(1.0, 0.0, 0.0),
 | 
				
			||||||
    vec3(0.0, 0.0, 0.0),
 | 
					    vec3(0.0, 1.0, 0.0),
 | 
				
			||||||
    vec3(0.0, 0.0, 0.0)
 | 
					    vec3(0.0, 0.0, 1.0)
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
layout(location = 0) out vec3 out_frag_color;
 | 
					layout(location = 0) out vec3 out_frag_color;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void main() 
 | 
					void main() 
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    gl_Position = view_projection * vec4(positions[gl_VertexIndex], 1.0);
 | 
					    gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
 | 
				
			||||||
    out_frag_color = colors[gl_VertexIndex];
 | 
					    out_frag_color = colors[gl_VertexIndex];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										2
									
								
								docs/.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								docs/.gitignore
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -1,5 +1,3 @@
 | 
				
			||||||
_build/
 | 
					_build/
 | 
				
			||||||
generated/
 | 
					generated/
 | 
				
			||||||
html/
 | 
					 | 
				
			||||||
xml/
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,86 +0,0 @@
 | 
				
			||||||
TARGET = ./
 | 
					 | 
				
			||||||
INPUT = "../modules"
 | 
					 | 
				
			||||||
RECURSIVE = YES
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
PROJECT_NAME           = "Light"
 | 
					 | 
				
			||||||
JAVADOC_AUTOBRIEF      = YES
 | 
					 | 
				
			||||||
JAVADOC_BANNER         = YES
 | 
					 | 
				
			||||||
GENERATE_XML           = YES
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
EXTRACT_PRIVATE = NO
 | 
					 | 
				
			||||||
EXTRACT_STATIC = NO
 | 
					 | 
				
			||||||
EXTRACT_LOCAL_CLASSES = NO
 | 
					 | 
				
			||||||
HIDE_UNDOC_RELATIONS = YES
 | 
					 | 
				
			||||||
HAVE_DOT = NO
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
GENERATE_TODOLIST      = NO
 | 
					 | 
				
			||||||
GENERATE_HTML          = NO
 | 
					 | 
				
			||||||
GENERATE_DOCSET        = NO
 | 
					 | 
				
			||||||
GENERATE_HTMLHELP      = NO
 | 
					 | 
				
			||||||
GENERATE_CHI           = NO
 | 
					 | 
				
			||||||
GENERATE_QHP           = NO
 | 
					 | 
				
			||||||
GENERATE_ECLIPSEHELP   = NO
 | 
					 | 
				
			||||||
GENERATE_TREEVIEW      = NO
 | 
					 | 
				
			||||||
GENERATE_LATEX         = NO
 | 
					 | 
				
			||||||
GENERATE_RTF           = NO
 | 
					 | 
				
			||||||
GENERATE_MAN           = NO
 | 
					 | 
				
			||||||
GENERATE_DOCBOOK       = NO
 | 
					 | 
				
			||||||
GENERATE_AUTOGEN_DEF   = NO
 | 
					 | 
				
			||||||
GENERATE_SQLITE3       = NO
 | 
					 | 
				
			||||||
GENERATE_PERLMOD       = NO
 | 
					 | 
				
			||||||
GENERATE_TAGFILE       = NO
 | 
					 | 
				
			||||||
GENERATE_LEGEND        = NO
 | 
					 | 
				
			||||||
GENERATE_TESTLIST      = NO
 | 
					 | 
				
			||||||
GENERATE_BUGLIST       = NO
 | 
					 | 
				
			||||||
GENERATE_DEPRECATEDLIST= NO
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
FILE_PATTERNS          = *.c \
 | 
					 | 
				
			||||||
                         *.cc \
 | 
					 | 
				
			||||||
                         *.cxx \
 | 
					 | 
				
			||||||
                         *.cxxm \
 | 
					 | 
				
			||||||
                         *.cpp \
 | 
					 | 
				
			||||||
                         *.cppm \
 | 
					 | 
				
			||||||
                         *.ccm \
 | 
					 | 
				
			||||||
                         *.c++ \
 | 
					 | 
				
			||||||
                         *.c++m \
 | 
					 | 
				
			||||||
                         *.java \
 | 
					 | 
				
			||||||
                         *.ii \
 | 
					 | 
				
			||||||
                         *.ixx \
 | 
					 | 
				
			||||||
                         *.ipp \
 | 
					 | 
				
			||||||
                         *.i++ \
 | 
					 | 
				
			||||||
                         *.inl \
 | 
					 | 
				
			||||||
                         *.idl \
 | 
					 | 
				
			||||||
                         *.ddl \
 | 
					 | 
				
			||||||
                         *.odl \
 | 
					 | 
				
			||||||
                         *.h \
 | 
					 | 
				
			||||||
                         *.hh \
 | 
					 | 
				
			||||||
                         *.hxx \
 | 
					 | 
				
			||||||
                         *.hpp \
 | 
					 | 
				
			||||||
                         *.h++ \
 | 
					 | 
				
			||||||
                         *.l \
 | 
					 | 
				
			||||||
                         *.cs \
 | 
					 | 
				
			||||||
                         *.d \
 | 
					 | 
				
			||||||
                         *.php \
 | 
					 | 
				
			||||||
                         *.php4 \
 | 
					 | 
				
			||||||
                         *.php5 \
 | 
					 | 
				
			||||||
                         *.phtml \
 | 
					 | 
				
			||||||
                         *.inc \
 | 
					 | 
				
			||||||
                         *.m \
 | 
					 | 
				
			||||||
                         *.markdown \
 | 
					 | 
				
			||||||
                         *.md \
 | 
					 | 
				
			||||||
                         *.mm \
 | 
					 | 
				
			||||||
                         *.dox \
 | 
					 | 
				
			||||||
                         *.py \
 | 
					 | 
				
			||||||
                         *.pyw \
 | 
					 | 
				
			||||||
                         *.f90 \
 | 
					 | 
				
			||||||
                         *.f95 \
 | 
					 | 
				
			||||||
                         *.f03 \
 | 
					 | 
				
			||||||
                         *.f08 \
 | 
					 | 
				
			||||||
                         *.f18 \
 | 
					 | 
				
			||||||
                         *.f \
 | 
					 | 
				
			||||||
                         *.for \
 | 
					 | 
				
			||||||
                         *.vhd \
 | 
					 | 
				
			||||||
                         *.vhdl \
 | 
					 | 
				
			||||||
                         *.ucf \
 | 
					 | 
				
			||||||
                         *.qsf \
 | 
					 | 
				
			||||||
                         *.ice
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,17 +0,0 @@
 | 
				
			||||||
Application
 | 
					 | 
				
			||||||
===================================================================================================
 | 
					 | 
				
			||||||
.. toctree::
 | 
					 | 
				
			||||||
   :maxdepth: 3
 | 
					 | 
				
			||||||
   :caption: App
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Functions
 | 
					 | 
				
			||||||
---------------------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
.. doxygenfunction:: main
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Classes
 | 
					 | 
				
			||||||
---------------------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
.. doxygenclass:: lt::app::ISystem
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. doxygenstruct:: lt::app::TickInfo
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. doxygenstruct:: lt::app::TickResult
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,13 +0,0 @@
 | 
				
			||||||
Renderer
 | 
					 | 
				
			||||||
===================================================================================================
 | 
					 | 
				
			||||||
.. toctree::
 | 
					 | 
				
			||||||
   :maxdepth: 3
 | 
					 | 
				
			||||||
   :caption: App
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Classes
 | 
					 | 
				
			||||||
---------------------------------------------------------------------------------------------------
 | 
					 | 
				
			||||||
.. doxygenenum:: lt::renderer::Api
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. doxygenclass:: lt::renderer::System
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. doxygenstruct:: lt::renderer::components::Sprite
 | 
					 | 
				
			||||||
							
								
								
									
										14
									
								
								docs/conf.py
									
										
									
									
									
								
							
							
						
						
									
										14
									
								
								docs/conf.py
									
										
									
									
									
								
							| 
						 | 
					@ -13,21 +13,13 @@ author = 'light7734'
 | 
				
			||||||
# -- General configuration ---------------------------------------------------
 | 
					# -- General configuration ---------------------------------------------------
 | 
				
			||||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
 | 
					# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extensions = ['breathe']
 | 
					extensions = []
 | 
				
			||||||
 | 
					 | 
				
			||||||
breathe_projects = {"Light": "./xml"}
 | 
					 | 
				
			||||||
breathe_default_project = "Light"
 | 
					 | 
				
			||||||
breathe_default_members = ()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Tell sphinx what the primary language being documented is.
 | 
					 | 
				
			||||||
primary_domain = 'cpp'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Tell sphinx what the pygments highlight language should be.
 | 
					 | 
				
			||||||
highlight_language = 'cpp'
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
templates_path = ['_templates']
 | 
					templates_path = ['_templates']
 | 
				
			||||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
 | 
					exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# -- Options for HTML output -------------------------------------------------
 | 
					# -- Options for HTML output -------------------------------------------------
 | 
				
			||||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
 | 
					# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										68
									
								
								docs/generate_changelog.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								docs/generate_changelog.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,68 @@
 | 
				
			||||||
 | 
					from git import Repo
 | 
				
			||||||
 | 
					import re
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					repo = Repo(search_parent_directories=True)
 | 
				
			||||||
 | 
					assert not repo.bare
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					file_path = "generated/changelog.rst"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					messages = []
 | 
				
			||||||
 | 
					short_shas = []
 | 
				
			||||||
 | 
					hex_shas = []
 | 
				
			||||||
 | 
					logs = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					remote_url = "https://git.light7734.com/light7734/light/commit"
 | 
				
			||||||
 | 
					def format_log(commit_type, message, major, minor, patch, short_sha, hex_sha):
 | 
				
			||||||
 | 
					    href = f"{remote_url}/{hex_sha}"
 | 
				
			||||||
 | 
					    version = f"{major}.{minor}.{patch}-kitten+{short_sha}";
 | 
				
			||||||
 | 
					    link = f"`{version} <{remote_url}/{hex_sha}>`__"
 | 
				
			||||||
 | 
					    return f"| **{message}** ({link})"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for commit in repo.iter_commits():
 | 
				
			||||||
 | 
					    messages.append(commit.summary)
 | 
				
			||||||
 | 
					    short_shas.append(repo.git.rev_parse(commit.hexsha, short=5))
 | 
				
			||||||
 | 
					    hex_shas.append(commit.hexsha)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ver_major = 0
 | 
				
			||||||
 | 
					ver_minor = 0
 | 
				
			||||||
 | 
					ver_patch = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					idx = len(messages)
 | 
				
			||||||
 | 
					for message in reversed(messages):
 | 
				
			||||||
 | 
					    idx = idx - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    commit_type = re.match("^(feat|fix|refactor|perf|build|asset|test|chore|ci|docs)", message)
 | 
				
			||||||
 | 
					    if not commit_type:
 | 
				
			||||||
 | 
					        continue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    match commit_type.group(0):
 | 
				
			||||||
 | 
					        case "feat":
 | 
				
			||||||
 | 
					            ver_minor = ver_minor + 1
 | 
				
			||||||
 | 
					            ver_patch = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case "fix":
 | 
				
			||||||
 | 
					            ver_patch = ver_patch + 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case "refactor":
 | 
				
			||||||
 | 
					            ver_patch = ver_patch + 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case "perf":
 | 
				
			||||||
 | 
					            ver_patch = ver_patch + 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case "build":
 | 
				
			||||||
 | 
					            ver_patch = ver_patch + 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        case "asset":
 | 
				
			||||||
 | 
					            ver_patch = ver_patch + 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    logs.append(format_log(commit_type, message, ver_major, ver_minor, ver_patch, short_shas[idx], hex_shas[idx]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					with open(file_path, "w") as f:
 | 
				
			||||||
 | 
					    f.write(".. changelogs\n\n\n")
 | 
				
			||||||
 | 
					    f.write("Changelogs\n")
 | 
				
			||||||
 | 
					    f.write("==================================================\n\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    f.write("KITTEN\n")
 | 
				
			||||||
 | 
					    f.write("--------------------------------------------------\n\n")
 | 
				
			||||||
 | 
					    for log in reversed(logs):
 | 
				
			||||||
 | 
					          f.write(log + '\n')
 | 
				
			||||||
| 
						 | 
					@ -23,10 +23,10 @@
 | 
				
			||||||
   guidelines/conventions.rst
 | 
					   guidelines/conventions.rst
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. toctree::
 | 
					.. toctree::
 | 
				
			||||||
   :maxdepth: 3
 | 
					   :maxdepth: 2
 | 
				
			||||||
   :caption: API
 | 
					   :caption: Generated Docs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   api/app.rst
 | 
					   generated/api.rst
 | 
				
			||||||
   api/renderer.rst
 | 
					   generated/changelog.rst
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										35
									
								
								docs/make.bat
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								docs/make.bat
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,35 @@
 | 
				
			||||||
 | 
					@ECHO OFF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pushd %~dp0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM Command file for Sphinx documentation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if "%SPHINXBUILD%" == "" (
 | 
				
			||||||
 | 
						set SPHINXBUILD=sphinx-build
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					set SOURCEDIR=.
 | 
				
			||||||
 | 
					set BUILDDIR=_build
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%SPHINXBUILD% >NUL 2>NUL
 | 
				
			||||||
 | 
					if errorlevel 9009 (
 | 
				
			||||||
 | 
						echo.
 | 
				
			||||||
 | 
						echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
 | 
				
			||||||
 | 
						echo.installed, then set the SPHINXBUILD environment variable to point
 | 
				
			||||||
 | 
						echo.to the full path of the 'sphinx-build' executable. Alternatively you
 | 
				
			||||||
 | 
						echo.may add the Sphinx directory to PATH.
 | 
				
			||||||
 | 
						echo.
 | 
				
			||||||
 | 
						echo.If you don't have Sphinx installed, grab it from
 | 
				
			||||||
 | 
						echo.https://www.sphinx-doc.org/
 | 
				
			||||||
 | 
						exit /b 1
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if "%1" == "" goto help
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
 | 
				
			||||||
 | 
					goto end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:help
 | 
				
			||||||
 | 
					%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:end
 | 
				
			||||||
 | 
					popd
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,6 @@
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <app/application.hpp>
 | 
					#include <app/application.hpp>
 | 
				
			||||||
#include <logger/logger.hpp>
 | 
					 | 
				
			||||||
#include <memory/scope.hpp>
 | 
					#include <memory/scope.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
auto main(int argc, char *argv[]) -> int32_t
 | 
					auto main(int argc, char *argv[]) -> int32_t
 | 
				
			||||||
| 
						 | 
					@ -22,7 +21,7 @@ try
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
catch (const std::exception &exp)
 | 
					catch (const std::exception &exp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	lt::log::critical("Terminating due to uncaught exception:");
 | 
						log_crt("Terminating due to uncaught exception:");
 | 
				
			||||||
	lt::log::critical("\texception.what(): {}", exp.what());
 | 
						log_crt("\texception.what(): {}", exp.what());
 | 
				
			||||||
	return EXIT_FAILURE;
 | 
						return EXIT_FAILURE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,6 @@
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <chrono>
 | 
					#include <chrono>
 | 
				
			||||||
#include <logger/logger.hpp>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace lt::app {
 | 
					namespace lt::app {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -73,7 +72,7 @@ public:
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		auto diag = m_diagnosis.emplace_back(std::move(diagnosis));
 | 
							auto diag = m_diagnosis.emplace_back(std::move(diagnosis));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		log::debug("message: {}", diag.message);
 | 
							log_dbg("message: {}", diag.message);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] auto empty_diagnosis() const -> bool
 | 
						[[nodiscard]] auto empty_diagnosis() const -> bool
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,5 @@
 | 
				
			||||||
#include <asset_baker/bakers.hpp>
 | 
					#include <asset_baker/bakers.hpp>
 | 
				
			||||||
#include <assets/shader.hpp>
 | 
					#include <assets/shader.hpp>
 | 
				
			||||||
#include <logger/logger.hpp>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
auto main(int argc, char *argv[]) -> int32_t
 | 
					auto main(int argc, char *argv[]) -> int32_t
 | 
				
			||||||
try
 | 
					try
 | 
				
			||||||
| 
						 | 
					@ -35,8 +34,8 @@ try
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
catch (const std::exception &exp)
 | 
					catch (const std::exception &exp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	lt::log::critical("Terminating due to uncaught exception:");
 | 
						log_crt("Terminating due to uncaught exception:");
 | 
				
			||||||
	lt::log::critical("\texception.what: {}:", exp.what());
 | 
						log_crt("\texception.what: {}:", exp.what());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return EXIT_FAILURE;
 | 
						return EXIT_FAILURE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,6 @@
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <assets/shader.hpp>
 | 
					#include <assets/shader.hpp>
 | 
				
			||||||
#include <logger/logger.hpp>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
inline void bake_shader(
 | 
					inline void bake_shader(
 | 
				
			||||||
    const std::filesystem::path &in_path,
 | 
					    const std::filesystem::path &in_path,
 | 
				
			||||||
| 
						 | 
					@ -14,7 +13,7 @@ inline void bake_shader(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto glsl_path = in_path.string();
 | 
						auto glsl_path = in_path.string();
 | 
				
			||||||
	auto spv_path = std::format("{}.spv", glsl_path);
 | 
						auto spv_path = std::format("{}.spv", glsl_path);
 | 
				
			||||||
	lt::log::trace(
 | 
						log_trc(
 | 
				
			||||||
	    "Compiling {} shader {} -> {}",
 | 
						    "Compiling {} shader {} -> {}",
 | 
				
			||||||
	    type == vertex ? "vertex" : "fragment",
 | 
						    type == vertex ? "vertex" : "fragment",
 | 
				
			||||||
	    glsl_path,
 | 
						    glsl_path,
 | 
				
			||||||
| 
						 | 
					@ -47,7 +46,7 @@ inline void bake_shader(
 | 
				
			||||||
	auto bytes = std::vector<std::byte>(size);
 | 
						auto bytes = std::vector<std::byte>(size);
 | 
				
			||||||
	stream.seekg(0, std::ios::beg);
 | 
						stream.seekg(0, std::ios::beg);
 | 
				
			||||||
	stream.read((char *)bytes.data(), size); // NOLINT
 | 
						stream.read((char *)bytes.data(), size); // NOLINT
 | 
				
			||||||
	lt::log::debug("BYTES: {}", bytes.size());
 | 
						log_dbg("BYTES: {}", bytes.size());
 | 
				
			||||||
	stream.close();
 | 
						stream.close();
 | 
				
			||||||
	std::filesystem::remove(spv_path);
 | 
						std::filesystem::remove(spv_path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,3 +1,3 @@
 | 
				
			||||||
add_library_module(camera)
 | 
					add_library_module(camera camera.cpp scene.cpp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
target_link_libraries(camera INTERFACE math)
 | 
					target_link_libraries(camera PUBLIC math)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										6
									
								
								modules/camera/private/camera.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								modules/camera/private/camera.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,6 @@
 | 
				
			||||||
 | 
					#include <camera/camera.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace lt {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										84
									
								
								modules/camera/private/scene.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								modules/camera/private/scene.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,84 @@
 | 
				
			||||||
 | 
					#include <camera/camera.hpp>
 | 
				
			||||||
 | 
					#include <camera/component.hpp>
 | 
				
			||||||
 | 
					#include <math/algebra.hpp>
 | 
				
			||||||
 | 
					#include <math/trig.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace lt {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SceneCamera::SceneCamera()
 | 
				
			||||||
 | 
					    : m_orthographic_specification { .size = 1000.0f, .near_plane = -1.0f, .far_plane = 10000.0f }
 | 
				
			||||||
 | 
					    , m_perspective_specification { .vertical_fov = math::radians(45.0f),
 | 
				
			||||||
 | 
						                                .near_plane = 0.01f,
 | 
				
			||||||
 | 
						                                .far_plane = 10000.0f }
 | 
				
			||||||
 | 
					    , m_aspect_ratio(16.0f / 9.0f)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						calculate_projection();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SceneCamera::set_viewport_size(unsigned int width, unsigned int height)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						m_aspect_ratio = static_cast<float>(width) / static_cast<float>(height);
 | 
				
			||||||
 | 
						calculate_projection();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SceneCamera::set_projection_type(ProjectionType projection_type)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						m_projection_type = projection_type;
 | 
				
			||||||
 | 
						calculate_projection();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SceneCamera::set_orthographic_size(float size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						m_orthographic_specification.size = size;
 | 
				
			||||||
 | 
						calculate_projection();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SceneCamera::set_orthographic_far_plane(float far_plane)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						m_orthographic_specification.far_plane = far_plane;
 | 
				
			||||||
 | 
						calculate_projection();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SceneCamera::set_orthographic_near_plane(float near_plane)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						m_orthographic_specification.near_plane = near_plane;
 | 
				
			||||||
 | 
						calculate_projection();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SceneCamera::set_perspective_vertical_fov(float vertical_fov)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						m_perspective_specification.vertical_fov = vertical_fov;
 | 
				
			||||||
 | 
						calculate_projection();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SceneCamera::set_perspective_far_plane(float far_plane)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						m_perspective_specification.far_plane = far_plane;
 | 
				
			||||||
 | 
						calculate_projection();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SceneCamera::set_perspective_near_plane(float near_plane)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						m_perspective_specification.near_plane = near_plane;
 | 
				
			||||||
 | 
						calculate_projection();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SceneCamera::calculate_projection()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						// TODO(Light): implement ortho perspective
 | 
				
			||||||
 | 
						if (m_projection_type == ProjectionType::Orthographic)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							// throw std::runtime_error { "ortho perspective not supported yet" };
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// defaults to perspective for now...
 | 
				
			||||||
 | 
						m_projection = math::perspective(
 | 
				
			||||||
 | 
						    m_perspective_specification.vertical_fov,
 | 
				
			||||||
 | 
						    m_aspect_ratio,
 | 
				
			||||||
 | 
						    m_perspective_specification.near_plane,
 | 
				
			||||||
 | 
						    m_perspective_specification.far_plane
 | 
				
			||||||
 | 
						);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace lt
 | 
				
			||||||
							
								
								
									
										35
									
								
								modules/camera/public/camera.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								modules/camera/public/camera.hpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,35 @@
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <math/mat4.hpp>
 | 
				
			||||||
 | 
					#include <math/vec4.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace lt {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Camera
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						Camera() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						[[nodiscard]] auto get_projection() const -> const math::mat4 &
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return m_projection;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						[[nodiscard]] auto get_background_color() const -> const math::vec4 &
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return m_background_color;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void set_background_color(const math::vec4 &color)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							m_background_color = color;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					protected:
 | 
				
			||||||
 | 
						math::mat4 m_projection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						math::vec4 m_background_color = math::vec4(1.0f, 0.0f, 0.0f, 1.0f);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace lt
 | 
				
			||||||
							
								
								
									
										29
									
								
								modules/camera/public/component.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								modules/camera/public/component.hpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,29 @@
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <camera/scene.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace lt {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct CameraComponent
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						CameraComponent() = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						CameraComponent(const CameraComponent &) = default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						CameraComponent(SceneCamera _camera, bool _isPrimary = false)
 | 
				
			||||||
 | 
						    : camera(_camera)
 | 
				
			||||||
 | 
						    , isPrimary(_isPrimary)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						operator SceneCamera() const
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return camera;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SceneCamera camera;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool isPrimary {};
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace lt
 | 
				
			||||||
| 
						 | 
					@ -1,22 +0,0 @@
 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <math/mat4.hpp>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace lt::camera::components {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct PerspectiveCamera
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	float vertical_fov {};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	float near_plane {};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	float far_plane {};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	float aspect_ratio {};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	math::vec4 background_color;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bool is_primary {};
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} // namespace lt::camera::components
 | 
					 | 
				
			||||||
							
								
								
									
										100
									
								
								modules/camera/public/scene.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								modules/camera/public/scene.hpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,100 @@
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <camera/camera.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace lt {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SceneCamera: public Camera
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						enum class ProjectionType
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							Orthographic = 0,
 | 
				
			||||||
 | 
							Perspetcive = 1
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct OrthographicSpecification
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							float size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							float near_plane;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							float far_plane;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct PerspectiveSpecification
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							float vertical_fov;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							float near_plane;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							float far_plane;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SceneCamera();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void set_viewport_size(unsigned int width, unsigned int height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void set_projection_type(ProjectionType projection_type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void set_orthographic_size(float size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void set_orthographic_far_plane(float far_plane);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void set_orthographic_near_plane(float near_plane);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void set_perspective_vertical_fov(float vertical_fov);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void set_perspective_far_plane(float far_plane);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void set_perspective_near_plane(float near_plane);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						[[nodiscard]] auto get_orthographic_size() const -> float
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return m_orthographic_specification.size;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						[[nodiscard]] auto get_orthographic_far_plane() const -> float
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return m_orthographic_specification.far_plane;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						[[nodiscard]] auto get_orthographic_near_plane() const -> float
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return m_orthographic_specification.near_plane;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						[[nodiscard]] auto get_perspective_vertical_fov() const -> float
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return m_perspective_specification.vertical_fov;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						[[nodiscard]] auto get_perspective_far_plane() const -> float
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return m_perspective_specification.far_plane;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						[[nodiscard]] auto get_perspective_near_plane() const -> float
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return m_perspective_specification.near_plane;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						[[nodiscard]] auto get_projection_type() const -> ProjectionType
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return m_projection_type;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						OrthographicSpecification m_orthographic_specification;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						PerspectiveSpecification m_perspective_specification;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						float m_aspect_ratio;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ProjectionType m_projection_type { ProjectionType::Orthographic };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void calculate_projection();
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace lt
 | 
				
			||||||
| 
						 | 
					@ -15,7 +15,7 @@ void Instrumentor::end_session_impl()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (m_current_session_count == 0u)
 | 
						if (m_current_session_count == 0u)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		log::warn("0 profiling for the ended session");
 | 
							log_wrn("0 profiling for the ended session");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	m_current_session_count = 0u;
 | 
						m_current_session_count = 0u;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,7 @@
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <format>
 | 
					#include <format>
 | 
				
			||||||
 | 
					#include <logger/logger.hpp>
 | 
				
			||||||
#include <source_location>
 | 
					#include <source_location>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace lt {
 | 
					namespace lt {
 | 
				
			||||||
| 
						 | 
					@ -27,6 +28,7 @@ struct ensure
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename Expression_T, typename... Args_T>
 | 
					template<typename Expression_T, typename... Args_T>
 | 
				
			||||||
ensure(Expression_T, std::format_string<Args_T...>, Args_T &&...)
 | 
					ensure(Expression_T, std::format_string<Args_T...>, Args_T &&...)
 | 
				
			||||||
    -> ensure<Expression_T, Args_T...>;
 | 
					    -> ensure<Expression_T, Args_T...>;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -55,10 +55,10 @@ public:
 | 
				
			||||||
			auto new_capacity = std::max(static_cast<size_t>(identifier + 1), m_sparse.size() * 2);
 | 
								auto new_capacity = std::max(static_cast<size_t>(identifier + 1), m_sparse.size() * 2);
 | 
				
			||||||
			new_capacity = std::min(new_capacity, max_capacity);
 | 
								new_capacity = std::min(new_capacity, max_capacity);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// log::debug("Increasing sparse vector size:", m_dead_count);
 | 
								// log_dbg("Increasing sparse vector size:", m_dead_count);
 | 
				
			||||||
			// log::debug("\tdead_count: {}", m_dead_count);
 | 
								// log_dbg("\tdead_count: {}", m_dead_count);
 | 
				
			||||||
			// log::debug("\talive_count: {}", m_alive_count);
 | 
								// log_dbg("\talive_count: {}", m_alive_count);
 | 
				
			||||||
			// log::debug("\tsparse.size: {} -> {}", m_sparse.size(), new_capacity);
 | 
								// log_dbg("\tsparse.size: {} -> {}", m_sparse.size(), new_capacity);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			m_sparse.resize(new_capacity, null_identifier);
 | 
								m_sparse.resize(new_capacity, null_identifier);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -101,7 +101,7 @@ void System::on_key_press(const lt::surface::KeyPressedEvent &event)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (event.get_key() > m_keys.size())
 | 
						if (event.get_key() > m_keys.size())
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		log::debug(
 | 
							log_dbg(
 | 
				
			||||||
		    "Key code larger than key container size, implement platform-dependant "
 | 
							    "Key code larger than key container size, implement platform-dependant "
 | 
				
			||||||
		    "key-code-mapping!"
 | 
							    "key-code-mapping!"
 | 
				
			||||||
		);
 | 
							);
 | 
				
			||||||
| 
						 | 
					@ -116,7 +116,7 @@ void System::on_key_release(const lt::surface::KeyReleasedEvent &event)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (event.get_key() > m_keys.size())
 | 
						if (event.get_key() > m_keys.size())
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		log::debug(
 | 
							log_dbg(
 | 
				
			||||||
		    "Key code larger than key container size, implement platform-dependant "
 | 
							    "Key code larger than key container size, implement platform-dependant "
 | 
				
			||||||
		    "key-code-mapping!"
 | 
							    "key-code-mapping!"
 | 
				
			||||||
		);
 | 
							);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,2 +1 @@
 | 
				
			||||||
add_library_module(logger)
 | 
					add_library_module(logger logger.cpp)
 | 
				
			||||||
add_test_module(logger logger.test.cpp)
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										1
									
								
								modules/logger/private/logger.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								modules/logger/private/logger.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					#include <logger/logger.hpp>
 | 
				
			||||||
| 
						 | 
					@ -1,25 +0,0 @@
 | 
				
			||||||
#include <logger/logger.hpp>
 | 
					 | 
				
			||||||
#include <test/test.hpp>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using ::lt::test::Case;
 | 
					 | 
				
			||||||
using ::lt::test::Suite;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Suite suite = [] {
 | 
					 | 
				
			||||||
	Case { "no format" } = [] {
 | 
					 | 
				
			||||||
		lt::log::trace("trace");
 | 
					 | 
				
			||||||
		lt::log::debug("debug");
 | 
					 | 
				
			||||||
		lt::log::info("info");
 | 
					 | 
				
			||||||
		lt::log::warn("warn");
 | 
					 | 
				
			||||||
		lt::log::error("error");
 | 
					 | 
				
			||||||
		lt::log::critical("critical");
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Case { "formatted" } = [] {
 | 
					 | 
				
			||||||
		lt::log::trace("trace {}", 69);
 | 
					 | 
				
			||||||
		lt::log::debug("debug {}", 69);
 | 
					 | 
				
			||||||
		lt::log::info("info {}", 69);
 | 
					 | 
				
			||||||
		lt::log::warn("warn {}", 69);
 | 
					 | 
				
			||||||
		lt::log::error("error {}", 69);
 | 
					 | 
				
			||||||
		lt::log::critical("critical {}", 69);
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,17 +1,10 @@
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <cstdint>
 | 
					#include <format>
 | 
				
			||||||
#include <filesystem>
 | 
					#include <print>
 | 
				
			||||||
#include <fmt/chrono.h>
 | 
					 | 
				
			||||||
#include <fmt/format.h>
 | 
					 | 
				
			||||||
#include <source_location>
 | 
					 | 
				
			||||||
#include <thread>
 | 
					 | 
				
			||||||
#include <utility>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace lt::log {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Severity of a log message. */
 | 
					/** Severity of a log message. */
 | 
				
			||||||
enum class Level : uint8_t
 | 
					enum class LogLvl : uint8_t
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/** Lowest and most vebose log level, for tracing execution paths and events */
 | 
						/** Lowest and most vebose log level, for tracing execution paths and events */
 | 
				
			||||||
	trace = 0,
 | 
						trace = 0,
 | 
				
			||||||
| 
						 | 
					@ -35,152 +28,62 @@ enum class Level : uint8_t
 | 
				
			||||||
	off = 6,
 | 
						off = 6,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace details {
 | 
					/** Simple console logger */
 | 
				
			||||||
 | 
					class Logger
 | 
				
			||||||
inline auto thread_hash_id() noexcept -> std::uint64_t
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return static_cast<std::uint64_t>(std::hash<std::thread::id> {}(std::this_thread::get_id()));
 | 
					public:
 | 
				
			||||||
 | 
						void static show_imgui_window();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						template<typename... Args>
 | 
				
			||||||
 | 
						void static log(LogLvl lvl, std::format_string<Args...> fmt, Args &&...args) noexcept
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							std::ignore = lvl;
 | 
				
			||||||
 | 
							std::println(fmt, std::forward<Args>(args)...);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void static log(LogLvl lvl, const char *message) noexcept
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							std::ignore = lvl;
 | 
				
			||||||
 | 
							std::println("{}", message);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						Logger() = default;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename... Args>
 | 
				
			||||||
 | 
					void log_trc(std::format_string<Args...> fmt, Args &&...args) noexcept
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						Logger::log(LogLvl::trace, fmt, std::forward<Args>(args)...);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace details
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename... Args>
 | 
					template<typename... Args>
 | 
				
			||||||
struct [[maybe_unused]] print
 | 
					void log_dbg(std::format_string<Args...> fmt, Args &&...args) noexcept
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	[[maybe_unused]] print(
 | 
						Logger::log(LogLvl::debug, fmt, std::forward<Args>(args)...);
 | 
				
			||||||
	    Level level,
 | 
					}
 | 
				
			||||||
	    const std::source_location &location,
 | 
					 | 
				
			||||||
	    std::format_string<Args...> format,
 | 
					 | 
				
			||||||
	    Args &&...arguments
 | 
					 | 
				
			||||||
	) noexcept
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		constexpr auto to_string = [](Level level, auto location) {
 | 
					 | 
				
			||||||
			// clang-format off
 | 
					 | 
				
			||||||
			switch (level)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
			using enum Level;
 | 
					 | 
				
			||||||
			case trace   : return "\033[1;37m| trc |\033[0m";
 | 
					 | 
				
			||||||
			case debug   : return "\033[1;36m| dbg |\033[0m";
 | 
					 | 
				
			||||||
			case info    : return "\033[1;32m| inf |\033[0m";
 | 
					 | 
				
			||||||
			case warn    : return "\033[1;33m| wrn |\033[0m";
 | 
					 | 
				
			||||||
			case error   : return "\033[1;31m| err |\033[0m";
 | 
					 | 
				
			||||||
			case critical: return "\033[1;41m| crt |\033[0m";
 | 
					 | 
				
			||||||
			case off: return "off";
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			// clang-format on
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			std::unreachable();
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		const auto path = std::filesystem::path { location.file_name() };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		std::println(
 | 
					 | 
				
			||||||
		    "{} {} ==> {}",
 | 
					 | 
				
			||||||
		    to_string(level, location),
 | 
					 | 
				
			||||||
		    std::format("{}:{}", path.filename().c_str(), location.line()),
 | 
					 | 
				
			||||||
		    std::format(format, std::forward<Args>(arguments)...)
 | 
					 | 
				
			||||||
		);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename... Args>
 | 
					template<typename... Args>
 | 
				
			||||||
print(Level, const std::source_location &, std::format_string<Args...>, Args &&...) noexcept
 | 
					void log_inf(std::format_string<Args...> fmt, Args &&...args) noexcept
 | 
				
			||||||
    -> print<Args...>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename... Args>
 | 
					 | 
				
			||||||
struct [[maybe_unused]] trace
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	[[maybe_unused]] trace(
 | 
						Logger::log(LogLvl::info, fmt, std::forward<Args>(args)...);
 | 
				
			||||||
	    std::format_string<Args...> format,
 | 
					}
 | 
				
			||||||
	    Args &&...arguments,
 | 
					 | 
				
			||||||
	    const std::source_location &location = std::source_location::current()
 | 
					 | 
				
			||||||
	) noexcept
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		print(Level::trace, location, format, std::forward<Args>(arguments)...);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename... Args>
 | 
					template<typename... Args>
 | 
				
			||||||
trace(std::format_string<Args...>, Args &&...) noexcept -> trace<Args...>;
 | 
					void log_wrn(std::format_string<Args...> fmt, Args &&...args) noexcept
 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename... Args>
 | 
					 | 
				
			||||||
struct [[maybe_unused]] debug
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	[[maybe_unused]] debug(
 | 
						Logger::log(LogLvl::warn, fmt, std::forward<Args>(args)...);
 | 
				
			||||||
	    std::format_string<Args...> format,
 | 
					}
 | 
				
			||||||
	    Args &&...arguments,
 | 
					 | 
				
			||||||
	    const std::source_location &location = std::source_location::current()
 | 
					 | 
				
			||||||
	) noexcept
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		print(Level::debug, location, format, std::forward<Args>(arguments)...);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename... Args>
 | 
					template<typename... Args>
 | 
				
			||||||
debug(std::format_string<Args...>, Args &&...) noexcept -> debug<Args...>;
 | 
					void log_err(std::format_string<Args...> fmt, Args &&...args) noexcept
 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename... Args>
 | 
					 | 
				
			||||||
struct [[maybe_unused]] info
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	[[maybe_unused]] info(
 | 
						Logger::log(LogLvl::error, fmt, std::forward<Args>(args)...);
 | 
				
			||||||
	    std::format_string<Args...> format,
 | 
					}
 | 
				
			||||||
	    Args &&...arguments,
 | 
					 | 
				
			||||||
	    const std::source_location &location = std::source_location::current()
 | 
					 | 
				
			||||||
	) noexcept
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		print(Level::info, location, format, std::forward<Args>(arguments)...);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename... Args>
 | 
					template<typename... Args>
 | 
				
			||||||
info(std::format_string<Args...>, Args &&...) noexcept -> info<Args...>;
 | 
					void log_crt(std::format_string<Args...> fmt, Args &&...args) noexcept
 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename... Args>
 | 
					 | 
				
			||||||
struct [[maybe_unused]] warn
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	[[maybe_unused]] warn(
 | 
						Logger::log(LogLvl::critical, fmt, std::forward<Args>(args)...);
 | 
				
			||||||
	    std::format_string<Args...> format,
 | 
					}
 | 
				
			||||||
	    Args &&...arguments,
 | 
					 | 
				
			||||||
	    const std::source_location &location = std::source_location::current()
 | 
					 | 
				
			||||||
	) noexcept
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		print(Level::warn, location, format, std::forward<Args>(arguments)...);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename... Args>
 | 
					 | 
				
			||||||
warn(std::format_string<Args...>, Args &&...) noexcept -> warn<Args...>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename... Args>
 | 
					 | 
				
			||||||
struct [[maybe_unused]] error
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	[[maybe_unused]] error(
 | 
					 | 
				
			||||||
	    std::format_string<Args...> format,
 | 
					 | 
				
			||||||
	    Args &&...arguments,
 | 
					 | 
				
			||||||
	    const std::source_location &location = std::source_location::current()
 | 
					 | 
				
			||||||
	) noexcept
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		print(Level::error, location, format, std::forward<Args>(arguments)...);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename... Args>
 | 
					 | 
				
			||||||
error(std::format_string<Args...>, Args &&...) noexcept -> error<Args...>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename... Args>
 | 
					 | 
				
			||||||
struct [[maybe_unused]] critical
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	[[maybe_unused]] critical(
 | 
					 | 
				
			||||||
	    std::format_string<Args...> format,
 | 
					 | 
				
			||||||
	    Args &&...arguments,
 | 
					 | 
				
			||||||
	    const std::source_location &location = std::source_location::current()
 | 
					 | 
				
			||||||
	) noexcept
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		print(Level::critical, location, format, std::forward<Args>(arguments)...);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
template<typename... Args>
 | 
					 | 
				
			||||||
critical(std::format_string<Args...>, Args &&...) noexcept -> critical<Args...>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} // namespace lt::log
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,29 +31,25 @@ namespace lt::math {
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * the 1 at [z][3] is to save the Z axis into the resulting W for perspective division.
 | 
					 * the 1 at [z][3] is to save the Z axis into the resulting W for perspective division.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @ref Thanks to pikuma for explaining the math behind this:
 | 
					 * thanks to pikuma: https://www.youtube.com/watch?v=EqNcqBdrNyI
 | 
				
			||||||
 * https://www.youtube.com/watch?v=EqNcqBdrNyI
 | 
					 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
template<typename T>
 | 
					template<typename T>
 | 
				
			||||||
constexpr auto perspective(T field_of_view, T aspect_ratio, T z_near, T z_far)
 | 
					constexpr auto perspective(T field_of_view, T aspect_ratio, T z_near, T z_far)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const T half_fov_tan = std::tan(field_of_view / static_cast<T>(2));
 | 
						const T half_fov_tan = std::tan(field_of_view / static_cast<T>(2));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto result = mat4_impl<T>::identity();
 | 
						auto result = mat4_impl<T> { T { 0 } };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	result[0][0] = T { 1 } / (aspect_ratio * half_fov_tan);
 | 
						result[0][0] = T { 1 } / (aspect_ratio * half_fov_tan);
 | 
				
			||||||
	//
 | 
					
 | 
				
			||||||
	result[1][1] = T { 1 } / (half_fov_tan);
 | 
						result[1][1] = T { 1 } / (half_fov_tan);
 | 
				
			||||||
	//
 | 
					
 | 
				
			||||||
	//	result[2][2] = -(z_far + z_near) / (z_far - z_near);
 | 
						result[2][2] = -(z_far + z_near) / (z_far - z_near);
 | 
				
			||||||
	//
 | 
					
 | 
				
			||||||
	result[2][2] = z_far / (z_far - z_near);
 | 
					 | 
				
			||||||
	//
 | 
					 | 
				
			||||||
	result[2][3] = -T { 1 };
 | 
						result[2][3] = -T { 1 };
 | 
				
			||||||
	//
 | 
					
 | 
				
			||||||
	// result[3][2] = -(T { 2 } * z_far * z_near) / (z_far - z_near);
 | 
						result[3][2] = -(T { 2 } * z_far * z_near) / (z_far - z_near);
 | 
				
			||||||
	result[3][2] = -(z_far * z_near) / (z_far - z_near);
 | 
					
 | 
				
			||||||
	//
 | 
					 | 
				
			||||||
	return result;
 | 
						return result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,16 +0,0 @@
 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <math/vec3.hpp>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace lt::math::components {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct Transform
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	math::vec3 translation;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	math::vec3 scale;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	math::vec3 rotation;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} // namespace lt::math::components
 | 
					 | 
				
			||||||
| 
						 | 
					@ -9,7 +9,6 @@ template<typename T = float>
 | 
				
			||||||
struct mat4_impl
 | 
					struct mat4_impl
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	using Column_T = vec4_impl<T>;
 | 
						using Column_T = vec4_impl<T>;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	constexpr explicit mat4_impl(T scalar = 0)
 | 
						constexpr explicit mat4_impl(T scalar = 0)
 | 
				
			||||||
	    : values(
 | 
						    : values(
 | 
				
			||||||
	          {
 | 
						          {
 | 
				
			||||||
| 
						 | 
					@ -44,7 +43,7 @@ struct mat4_impl
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] static constexpr auto identity() -> mat4_impl<T>
 | 
						[[nodiscard]] constexpr auto identity() -> mat4_impl<T>
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return mat4_impl<T> {
 | 
							return mat4_impl<T> {
 | 
				
			||||||
			{ 1 }, {},    {},    {},    //
 | 
								{ 1 }, {},    {},    {},    //
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,5 @@
 | 
				
			||||||
add_library_module(libmirror)
 | 
					add_library_module(libmirror)
 | 
				
			||||||
target_link_libraries(libmirror INTERFACE app time input surface renderer
 | 
					target_link_libraries(libmirror INTERFACE app time input surface renderer)
 | 
				
			||||||
                                          camera)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
add_test_module(
 | 
					add_test_module(
 | 
				
			||||||
    libmirror layers/editor_layer.test.cpp panels/asset_browser.test.cpp
 | 
					    libmirror layers/editor_layer.test.cpp panels/asset_browser.test.cpp
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,11 +2,9 @@
 | 
				
			||||||
#include <app/application.hpp>
 | 
					#include <app/application.hpp>
 | 
				
			||||||
#include <app/entrypoint.hpp>
 | 
					#include <app/entrypoint.hpp>
 | 
				
			||||||
#include <app/system.hpp>
 | 
					#include <app/system.hpp>
 | 
				
			||||||
#include <camera/components.hpp>
 | 
					 | 
				
			||||||
#include <ecs/entity.hpp>
 | 
					#include <ecs/entity.hpp>
 | 
				
			||||||
#include <input/components.hpp>
 | 
					#include <input/components.hpp>
 | 
				
			||||||
#include <input/system.hpp>
 | 
					#include <input/system.hpp>
 | 
				
			||||||
#include <math/trig.hpp>
 | 
					 | 
				
			||||||
#include <math/vec2.hpp>
 | 
					#include <math/vec2.hpp>
 | 
				
			||||||
#include <memory/reference.hpp>
 | 
					#include <memory/reference.hpp>
 | 
				
			||||||
#include <memory/scope.hpp>
 | 
					#include <memory/scope.hpp>
 | 
				
			||||||
| 
						 | 
					@ -68,18 +66,13 @@ public:
 | 
				
			||||||
			const auto &[x, y] = surface.get_position();
 | 
								const auto &[x, y] = surface.get_position();
 | 
				
			||||||
			const auto &[width, height] = surface.get_resolution();
 | 
								const auto &[width, height] = surface.get_resolution();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (input.get_action(m_quit_action_key).state == State::active)
 | 
								if (input.get_action(m_quit_action_key).state == State::active)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				should_quit = true;
 | 
									should_quit = true;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (input.get_action(m_debug_action_keys[0]).state == State::active)
 | 
								if (input.get_action(m_debug_action_keys[0]).state == State::active)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				for (auto &[id, camera] :
 | 
									surface.push_request(surface::ModifyPositionRequest({ x + 5, y + 5 }));
 | 
				
			||||||
				     m_registry->view<lt::camera::components::PerspectiveCamera>())
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					camera.vertical_fov += (static_cast<float>(tick.delta_time.count()) * 40.0f);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (input.get_action(m_debug_action_keys[1]).state == State::active)
 | 
								if (input.get_action(m_debug_action_keys[1]).state == State::active)
 | 
				
			||||||
| 
						 | 
					@ -226,20 +219,6 @@ public:
 | 
				
			||||||
		        .callback = &renderer_callback,
 | 
							        .callback = &renderer_callback,
 | 
				
			||||||
		        .user_data = this,
 | 
							        .user_data = this,
 | 
				
			||||||
		    } });
 | 
							    } });
 | 
				
			||||||
 | 
					 | 
				
			||||||
		m_camera_id = m_editor_registry->create_entity();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		m_editor_registry->add(
 | 
					 | 
				
			||||||
		    m_camera_id,
 | 
					 | 
				
			||||||
		    camera::components::PerspectiveCamera {
 | 
					 | 
				
			||||||
		        .vertical_fov = math::radians(90.0f),
 | 
					 | 
				
			||||||
		        .near_plane = 0.1f,
 | 
					 | 
				
			||||||
		        .far_plane = 30.0,
 | 
					 | 
				
			||||||
		        .aspect_ratio = 1.0f,
 | 
					 | 
				
			||||||
		        .background_color = math::vec4(1.0, 0.0, 0.0, 1.0),
 | 
					 | 
				
			||||||
		        .is_primary = true,
 | 
					 | 
				
			||||||
		    }
 | 
					 | 
				
			||||||
		);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void setup_input_system()
 | 
						void setup_input_system()
 | 
				
			||||||
| 
						 | 
					@ -266,8 +245,6 @@ private:
 | 
				
			||||||
	memory::Ref<MirrorSystem> m_mirror_system;
 | 
						memory::Ref<MirrorSystem> m_mirror_system;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lt::ecs::EntityId m_window = lt::ecs::null_entity;
 | 
						lt::ecs::EntityId m_window = lt::ecs::null_entity;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	lt::ecs::EntityId m_camera_id = lt::ecs::null_entity;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
auto app::create_application() -> memory::Scope<app::Application>
 | 
					auto app::create_application() -> memory::Scope<app::Application>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,29 +8,21 @@ add_library_module(
 | 
				
			||||||
    backend/vk/context/instance.cpp
 | 
					    backend/vk/context/instance.cpp
 | 
				
			||||||
    backend/vk/context/surface.cpp
 | 
					    backend/vk/context/surface.cpp
 | 
				
			||||||
    backend/vk/context/swapchain.cpp
 | 
					    backend/vk/context/swapchain.cpp
 | 
				
			||||||
    backend/vk/data/buffer.cpp
 | 
					 | 
				
			||||||
    backend/vk/renderer/pass.cpp
 | 
					    backend/vk/renderer/pass.cpp
 | 
				
			||||||
    backend/vk/renderer/renderer.cpp
 | 
					    backend/vk/renderer/renderer.cpp
 | 
				
			||||||
    # frontend
 | 
					    # Vulkan - frontend
 | 
				
			||||||
    frontend/messenger.cpp
 | 
					    frontend/messenger.cpp
 | 
				
			||||||
    frontend/context/device.cpp
 | 
					    frontend/context/device.cpp
 | 
				
			||||||
    frontend/context/gpu.cpp
 | 
					    frontend/context/gpu.cpp
 | 
				
			||||||
    frontend/context/instance.cpp
 | 
					    frontend/context/instance.cpp
 | 
				
			||||||
    frontend/context/surface.cpp
 | 
					    frontend/context/surface.cpp
 | 
				
			||||||
    frontend/context/swapchain.cpp
 | 
					    frontend/context/swapchain.cpp
 | 
				
			||||||
    frontend/data/buffer.cpp
 | 
					 | 
				
			||||||
    frontend/renderer/renderer.cpp
 | 
					    frontend/renderer/renderer.cpp
 | 
				
			||||||
    frontend/renderer/pass.cpp)
 | 
					    frontend/renderer/pass.cpp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
target_link_libraries(
 | 
					target_link_libraries(
 | 
				
			||||||
    renderer
 | 
					    renderer
 | 
				
			||||||
    PUBLIC app
 | 
					    PUBLIC app ecs memory assets time bitwise
 | 
				
			||||||
           ecs
 | 
					 | 
				
			||||||
           memory
 | 
					 | 
				
			||||||
           assets
 | 
					 | 
				
			||||||
           time
 | 
					 | 
				
			||||||
           bitwise
 | 
					 | 
				
			||||||
           camera
 | 
					 | 
				
			||||||
    PRIVATE surface pthread)
 | 
					    PRIVATE surface pthread)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
add_test_module(
 | 
					add_test_module(
 | 
				
			||||||
| 
						 | 
					@ -42,10 +34,11 @@ add_test_module(
 | 
				
			||||||
    frontend/context/surface.test.cpp
 | 
					    frontend/context/surface.test.cpp
 | 
				
			||||||
    frontend/context/device.test.cpp
 | 
					    frontend/context/device.test.cpp
 | 
				
			||||||
    frontend/context/swapchain.test.cpp
 | 
					    frontend/context/swapchain.test.cpp
 | 
				
			||||||
    frontend/data/buffer.test.cpp
 | 
					    frontend/renderer/pass.test.cpp
 | 
				
			||||||
    # frontend/renderer/pass.test.cpp
 | 
					 | 
				
			||||||
    frontend/renderer/renderer.test.cpp
 | 
					    frontend/renderer/renderer.test.cpp
 | 
				
			||||||
    # backend specific tests -- vk
 | 
					    # backend specific tests -- vk
 | 
				
			||||||
    backend/vk/context/instance.test.cpp)
 | 
					    backend/vk/context/instance.test.cpp
 | 
				
			||||||
 | 
					    # backend specific tests -- dx backend specific tests -- mt
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
target_link_libraries(renderer_tests PRIVATE surface pthread)
 | 
					target_link_libraries(renderer_tests PRIVATE surface pthread)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -75,17 +75,10 @@ void Device::initialize_logical_device()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto extensions = std::vector<const char *> {
 | 
						auto extensions = std::vector<const char *> {
 | 
				
			||||||
		VK_KHR_SWAPCHAIN_EXTENSION_NAME,
 | 
							VK_KHR_SWAPCHAIN_EXTENSION_NAME,
 | 
				
			||||||
		VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME,
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	const auto dynamic_rendering_features = VkPhysicalDeviceDynamicRenderingFeatures {
 | 
					 | 
				
			||||||
		.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES,
 | 
					 | 
				
			||||||
		.dynamicRendering = true,
 | 
					 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto device_info = VkDeviceCreateInfo {
 | 
						auto device_info = VkDeviceCreateInfo {
 | 
				
			||||||
		.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
 | 
							.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
 | 
				
			||||||
		.pNext = &dynamic_rendering_features,
 | 
					 | 
				
			||||||
		.queueCreateInfoCount = static_cast<uint32_t>(queue_infos.size()),
 | 
							.queueCreateInfoCount = static_cast<uint32_t>(queue_infos.size()),
 | 
				
			||||||
		.pQueueCreateInfos = queue_infos.data(),
 | 
							.pQueueCreateInfos = queue_infos.data(),
 | 
				
			||||||
		.enabledExtensionCount = static_cast<uint32_t>(extensions.size()),
 | 
							.enabledExtensionCount = static_cast<uint32_t>(extensions.size()),
 | 
				
			||||||
| 
						 | 
					@ -214,31 +207,6 @@ void Device::wait_for_fences(std::span<VkFence> fences) const
 | 
				
			||||||
	return images;
 | 
						return images;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[nodiscard]] auto Device::get_memory_requirements(VkBuffer buffer) const -> VkMemoryRequirements
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	auto requirements = VkMemoryRequirements {};
 | 
					 | 
				
			||||||
	vk_get_buffer_memory_requirements(m_device, buffer, &requirements);
 | 
					 | 
				
			||||||
	return requirements;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void Device::bind_memory(VkBuffer buffer, VkDeviceMemory memory, size_t offset /* = 0u */) const
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	vkc(vk_bind_buffer_memory(m_device, buffer, memory, offset));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[nodiscard]] auto Device::map_memory(VkDeviceMemory memory, size_t size, size_t offset) const
 | 
					 | 
				
			||||||
    -> std::span<std::byte>
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	void *data = {};
 | 
					 | 
				
			||||||
	vkc(vk_map_memory(m_device, memory, offset, size, {}, &data));
 | 
					 | 
				
			||||||
	return { std::bit_cast<std::byte *>(data), size };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void Device::unmap_memory(VkDeviceMemory memory)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	vk_unmap_memory(m_device, memory);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[nodiscard]] auto Device::create_swapchain(VkSwapchainCreateInfoKHR info) const -> VkSwapchainKHR
 | 
					[[nodiscard]] auto Device::create_swapchain(VkSwapchainCreateInfoKHR info) const -> VkSwapchainKHR
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	auto *swapchain = VkSwapchainKHR {};
 | 
						auto *swapchain = VkSwapchainKHR {};
 | 
				
			||||||
| 
						 | 
					@ -283,18 +251,9 @@ void Device::unmap_memory(VkDeviceMemory memory)
 | 
				
			||||||
	return pass;
 | 
						return pass;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[nodiscard]] auto Device::create_pipeline_layout(
 | 
					[[nodiscard]] auto Device::create_pipeline_layout(VkPipelineLayoutCreateInfo info) const
 | 
				
			||||||
    std::vector<VkPushConstantRange> push_constant_ranges
 | 
					    -> VkPipelineLayout
 | 
				
			||||||
) const -> VkPipelineLayout
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	auto info = VkPipelineLayoutCreateInfo {
 | 
					 | 
				
			||||||
		.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
 | 
					 | 
				
			||||||
		.setLayoutCount = 0u,
 | 
					 | 
				
			||||||
		.pSetLayouts = nullptr,
 | 
					 | 
				
			||||||
		.pushConstantRangeCount = static_cast<uint32_t>(push_constant_ranges.size()),
 | 
					 | 
				
			||||||
		.pPushConstantRanges = push_constant_ranges.data(),
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	auto *pipeline_layout = VkPipelineLayout {};
 | 
						auto *pipeline_layout = VkPipelineLayout {};
 | 
				
			||||||
	vkc(vk_create_pipeline_layout(m_device, &info, nullptr, &pipeline_layout));
 | 
						vkc(vk_create_pipeline_layout(m_device, &info, nullptr, &pipeline_layout));
 | 
				
			||||||
	return pipeline_layout;
 | 
						return pipeline_layout;
 | 
				
			||||||
| 
						 | 
					@ -340,13 +299,6 @@ void Device::unmap_memory(VkDeviceMemory memory)
 | 
				
			||||||
	return fences;
 | 
						return fences;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[nodiscard]] auto Device::create_buffer(VkBufferCreateInfo info) const -> VkBuffer
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	auto *buffer = VkBuffer {};
 | 
					 | 
				
			||||||
	vkc(vk_create_buffer(m_device, &info, nullptr, &buffer));
 | 
					 | 
				
			||||||
	return buffer;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[nodiscard]] auto Device::allocate_command_buffers(VkCommandBufferAllocateInfo info) const
 | 
					[[nodiscard]] auto Device::allocate_command_buffers(VkCommandBufferAllocateInfo info) const
 | 
				
			||||||
    -> std::vector<VkCommandBuffer>
 | 
					    -> std::vector<VkCommandBuffer>
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -355,18 +307,6 @@ void Device::unmap_memory(VkDeviceMemory memory)
 | 
				
			||||||
	return command_buffers;
 | 
						return command_buffers;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[nodiscard]] auto Device::allocate_memory(VkMemoryAllocateInfo info) const -> VkDeviceMemory
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	auto *memory = VkDeviceMemory {};
 | 
					 | 
				
			||||||
	vkc(vk_allocate_memory(m_device, &info, nullptr, &memory));
 | 
					 | 
				
			||||||
	return memory;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void Device::free_memory(VkDeviceMemory memory) const
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	vk_free_memory(m_device, memory, nullptr);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void Device::destroy_swapchain(VkSwapchainKHR swapchain) const
 | 
					void Device::destroy_swapchain(VkSwapchainKHR swapchain) const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	vk_destroy_swapchain_khr(m_device, swapchain, m_allocator);
 | 
						vk_destroy_swapchain_khr(m_device, swapchain, m_allocator);
 | 
				
			||||||
| 
						 | 
					@ -449,9 +389,4 @@ void Device::destroy_fences(std::span<VkFence> fences) const
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Device::destroy_buffer(VkBuffer buffer) const
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	vk_destroy_buffer(m_device, buffer, nullptr);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} // namespace lt::renderer::vk
 | 
					} // namespace lt::renderer::vk
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -96,16 +96,6 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] auto get_swapchain_images(VkSwapchainKHR swapchain) const -> std::vector<VkImage>;
 | 
						[[nodiscard]] auto get_swapchain_images(VkSwapchainKHR swapchain) const -> std::vector<VkImage>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] auto get_memory_requirements(VkBuffer buffer) const -> VkMemoryRequirements;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/** binders / mappers  */
 | 
					 | 
				
			||||||
	void bind_memory(VkBuffer buffer, VkDeviceMemory memory, size_t offset = 0u) const;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	[[nodiscard]] auto map_memory(VkDeviceMemory memory, size_t size, size_t offset) const
 | 
					 | 
				
			||||||
	    -> std::span<std::byte>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void unmap_memory(VkDeviceMemory memory);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/** create functions */
 | 
						/** create functions */
 | 
				
			||||||
	[[nodiscard]] auto create_swapchain(VkSwapchainCreateInfoKHR info) const -> VkSwapchainKHR;
 | 
						[[nodiscard]] auto create_swapchain(VkSwapchainCreateInfoKHR info) const -> VkSwapchainKHR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -118,9 +108,8 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] auto create_pass(VkRenderPassCreateInfo info) const -> VkRenderPass;
 | 
						[[nodiscard]] auto create_pass(VkRenderPassCreateInfo info) const -> VkRenderPass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] auto create_pipeline_layout(
 | 
						[[nodiscard]] auto create_pipeline_layout(VkPipelineLayoutCreateInfo info) const
 | 
				
			||||||
	    std::vector<VkPushConstantRange> push_constant_ranges
 | 
						    -> VkPipelineLayout;
 | 
				
			||||||
	) const -> VkPipelineLayout;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] auto create_shader_module(VkShaderModuleCreateInfo info) const -> VkShaderModule;
 | 
						[[nodiscard]] auto create_shader_module(VkShaderModuleCreateInfo info) const -> VkShaderModule;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -131,17 +120,10 @@ public:
 | 
				
			||||||
	[[nodiscard]] auto create_fences(VkFenceCreateInfo info, uint32_t count) const
 | 
						[[nodiscard]] auto create_fences(VkFenceCreateInfo info, uint32_t count) const
 | 
				
			||||||
	    -> std::vector<VkFence>;
 | 
						    -> std::vector<VkFence>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] auto create_buffer(VkBufferCreateInfo info) const -> VkBuffer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/** allocation functions */
 | 
						/** allocation functions */
 | 
				
			||||||
	[[nodiscard]] auto allocate_memory(VkMemoryAllocateInfo info) const -> VkDeviceMemory;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	[[nodiscard]] auto allocate_command_buffers(VkCommandBufferAllocateInfo info) const
 | 
						[[nodiscard]] auto allocate_command_buffers(VkCommandBufferAllocateInfo info) const
 | 
				
			||||||
	    -> std::vector<VkCommandBuffer>;
 | 
						    -> std::vector<VkCommandBuffer>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/** de-allocation functions */
 | 
					 | 
				
			||||||
	void free_memory(VkDeviceMemory memory) const;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/** destroy functions */
 | 
						/** destroy functions */
 | 
				
			||||||
	void destroy_swapchain(VkSwapchainKHR swapchain) const;
 | 
						void destroy_swapchain(VkSwapchainKHR swapchain) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -171,8 +153,6 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void destroy_fences(std::span<VkFence> fences) const;
 | 
						void destroy_fences(std::span<VkFence> fences) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void destroy_buffer(VkBuffer buffer) const;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	template<typename T>
 | 
						template<typename T>
 | 
				
			||||||
	static auto get_object_type(const T &object) -> VkObjectType
 | 
						static auto get_object_type(const T &object) -> VkObjectType
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,38 +5,35 @@
 | 
				
			||||||
namespace lt::renderer::vk {
 | 
					namespace lt::renderer::vk {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Gpu::Gpu(IInstance *instance)
 | 
					Gpu::Gpu(IInstance *instance)
 | 
				
			||||||
    : m_descriptor_indexing_features(
 | 
					 | 
				
			||||||
          { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES }
 | 
					 | 
				
			||||||
      )
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	auto gpus = static_cast<Instance *>(instance)->enumerate_gpus();
 | 
						auto gpus = static_cast<Instance *>(instance)->enumerate_gpus();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (auto &gpu : gpus)
 | 
						for (auto &gpu : gpus)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		auto properties = VkPhysicalDeviceProperties {};
 | 
							auto properties = VkPhysicalDeviceProperties {};
 | 
				
			||||||
		auto features = VkPhysicalDeviceFeatures2 {
 | 
							auto features = VkPhysicalDeviceFeatures {};
 | 
				
			||||||
			.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
 | 
					 | 
				
			||||||
			.pNext = &m_descriptor_indexing_features
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		vk_get_physical_device_properties(gpu, &properties);
 | 
							vk_get_physical_device_properties(gpu, &properties);
 | 
				
			||||||
		vk_get_physical_device_features(gpu, &features);
 | 
							vk_get_physical_device_features(gpu, &features);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU
 | 
							if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU
 | 
				
			||||||
		    && features.features.geometryShader)
 | 
							    && features.geometryShader)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			m_gpu = gpu;
 | 
								m_gpu = gpu;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	ensure(m_gpu, "Failed to find any suitable Vulkan physical device");
 | 
						ensure(m_gpu, "Failed to find any suitable Vulkan physical device");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[nodiscard]] auto Gpu::get_queue_family_properties() const -> std::vector<VkQueueFamilyProperties>
 | 
				
			||||||
	vk_get_physical_device_memory_properties(m_gpu, &m_memory_properties);
 | 
					{
 | 
				
			||||||
 | 
					 | 
				
			||||||
	auto count = uint32_t { 0u };
 | 
						auto count = uint32_t { 0u };
 | 
				
			||||||
	vk_get_physical_device_queue_family_properties(m_gpu, &count, nullptr);
 | 
						vk_get_physical_device_queue_family_properties(m_gpu, &count, nullptr);
 | 
				
			||||||
	m_queue_family_properties.resize(count);
 | 
					
 | 
				
			||||||
	vk_get_physical_device_queue_family_properties(m_gpu, &count, m_queue_family_properties.data());
 | 
						auto properties = std::vector<VkQueueFamilyProperties>(count);
 | 
				
			||||||
 | 
						vk_get_physical_device_queue_family_properties(m_gpu, &count, properties.data());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return properties;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[nodiscard]] auto Gpu::queue_family_supports_presentation(
 | 
					[[nodiscard]] auto Gpu::queue_family_supports_presentation(
 | 
				
			||||||
| 
						 | 
					@ -70,11 +67,5 @@ Gpu::Gpu(IInstance *instance)
 | 
				
			||||||
	return formats;
 | 
						return formats;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[nodiscard]] auto Gpu::create_device(VkDeviceCreateInfo info) const -> VkDevice
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	auto *device = VkDevice {};
 | 
					 | 
				
			||||||
	vkc(vk_create_device(m_gpu, &info, nullptr, &device));
 | 
					 | 
				
			||||||
	return device;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace lt::renderer::vk
 | 
					} // namespace lt::renderer::vk
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,6 +12,13 @@ class Gpu: public IGpu
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	Gpu(IInstance *instance);
 | 
						Gpu(IInstance *instance);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						[[nodiscard]] auto vk() const -> VkPhysicalDevice
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return m_gpu;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						[[nodiscard]] auto get_queue_family_properties() const -> std::vector<VkQueueFamilyProperties>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] auto queue_family_supports_presentation(
 | 
						[[nodiscard]] auto queue_family_supports_presentation(
 | 
				
			||||||
	    VkSurfaceKHR surface,
 | 
						    VkSurfaceKHR surface,
 | 
				
			||||||
	    uint32_t queue_family_idx
 | 
						    uint32_t queue_family_idx
 | 
				
			||||||
| 
						 | 
					@ -23,39 +30,8 @@ public:
 | 
				
			||||||
	[[nodiscard]] auto get_surface_formats(VkSurfaceKHR surface) const
 | 
						[[nodiscard]] auto get_surface_formats(VkSurfaceKHR surface) const
 | 
				
			||||||
	    -> std::vector<VkSurfaceFormatKHR>;
 | 
						    -> std::vector<VkSurfaceFormatKHR>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] auto create_device(VkDeviceCreateInfo info) const -> VkDevice;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	[[nodiscard]] auto get_properties() const -> VkPhysicalDeviceProperties
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		return m_properties;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	[[nodiscard]] auto get_descriptor_indexing_features() const
 | 
					 | 
				
			||||||
	    -> VkPhysicalDeviceDescriptorIndexingFeatures
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		return m_descriptor_indexing_features;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	[[nodiscard]] auto get_memory_properties() const -> VkPhysicalDeviceMemoryProperties
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		return m_memory_properties;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	[[nodiscard]] auto get_queue_family_properties() const -> std::vector<VkQueueFamilyProperties>
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		return m_queue_family_properties;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	memory::NullOnMove<VkPhysicalDevice> m_gpu = VK_NULL_HANDLE;
 | 
						memory::NullOnMove<VkPhysicalDevice> m_gpu = VK_NULL_HANDLE;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	VkPhysicalDeviceProperties m_properties {};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	VkPhysicalDeviceDescriptorIndexingFeatures m_descriptor_indexing_features;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	VkPhysicalDeviceMemoryProperties m_memory_properties {};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	std::vector<VkQueueFamilyProperties> m_queue_family_properties;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace lt::renderer::vk
 | 
					} // namespace lt::renderer::vk
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,9 +29,8 @@ PFN_vkGetPhysicalDeviceQueueFamilyProperties vk_get_physical_device_queue_family
 | 
				
			||||||
PFN_vkCreateDevice vk_create_device {};
 | 
					PFN_vkCreateDevice vk_create_device {};
 | 
				
			||||||
PFN_vkGetDeviceProcAddr vk_get_device_proc_address {};
 | 
					PFN_vkGetDeviceProcAddr vk_get_device_proc_address {};
 | 
				
			||||||
PFN_vkDestroyDevice vk_destroy_device {};
 | 
					PFN_vkDestroyDevice vk_destroy_device {};
 | 
				
			||||||
PFN_vkGetPhysicalDeviceFeatures2 vk_get_physical_device_features {};
 | 
					PFN_vkGetPhysicalDeviceFeatures vk_get_physical_device_features {};
 | 
				
			||||||
PFN_vkEnumerateDeviceExtensionProperties vk_enumerate_device_extension_properties {};
 | 
					PFN_vkEnumerateDeviceExtensionProperties vk_enumerate_device_extension_properties {};
 | 
				
			||||||
PFN_vkGetPhysicalDeviceMemoryProperties vk_get_physical_device_memory_properties {};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// extension instance functions
 | 
					// extension instance functions
 | 
				
			||||||
PFN_vkCmdBeginDebugUtilsLabelEXT vk_cmd_begin_debug_label {};
 | 
					PFN_vkCmdBeginDebugUtilsLabelEXT vk_cmd_begin_debug_label {};
 | 
				
			||||||
| 
						 | 
					@ -87,37 +86,15 @@ PFN_vkCmdBindPipeline vk_cmd_bind_pipeline {};
 | 
				
			||||||
PFN_vkCmdDraw vk_cmd_draw {};
 | 
					PFN_vkCmdDraw vk_cmd_draw {};
 | 
				
			||||||
PFN_vkCmdSetViewport vk_cmd_set_viewport {};
 | 
					PFN_vkCmdSetViewport vk_cmd_set_viewport {};
 | 
				
			||||||
PFN_vkCmdSetScissor vk_cmd_set_scissors {};
 | 
					PFN_vkCmdSetScissor vk_cmd_set_scissors {};
 | 
				
			||||||
PFN_vkCmdPushConstants vk_cmd_push_constants {};
 | 
					 | 
				
			||||||
PFN_vkCmdCopyBuffer vk_cmd_copy_buffer {};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
PFN_vkCreateDescriptorSetLayout vk_create_descriptor_set_layout {};
 | 
					 | 
				
			||||||
PFN_vkDestroyDescriptorSetLayout vk_destroy_descriptor_set_layout {};
 | 
					 | 
				
			||||||
PFN_vkCreateDescriptorPool vk_create_descriptor_pool {};
 | 
					 | 
				
			||||||
PFN_vkDestroyDescriptorPool vk_destroy_descriptor_pool {};
 | 
					 | 
				
			||||||
PFN_vkAllocateDescriptorSets vk_allocate_descriptor_sets {};
 | 
					 | 
				
			||||||
PFN_vkFreeDescriptorSets vk_free_descriptor_sets {};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
PFN_vkCreateBuffer vk_create_buffer {};
 | 
					 | 
				
			||||||
PFN_vkDestroyBuffer vk_destroy_buffer {};
 | 
					 | 
				
			||||||
PFN_vkGetBufferMemoryRequirements vk_get_buffer_memory_requirements {};
 | 
					 | 
				
			||||||
PFN_vkAllocateMemory vk_allocate_memory {};
 | 
					 | 
				
			||||||
PFN_vkBindBufferMemory vk_bind_buffer_memory {};
 | 
					 | 
				
			||||||
PFN_vkMapMemory vk_map_memory {};
 | 
					 | 
				
			||||||
PFN_vkUnmapMemory vk_unmap_memory {};
 | 
					 | 
				
			||||||
PFN_vkFreeMemory vk_free_memory {};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
PFN_vkResetCommandBuffer vk_reset_command_buffer {};
 | 
					PFN_vkResetCommandBuffer vk_reset_command_buffer {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PFN_vkCmdBeginRendering vk_cmd_begin_rendering {};
 | 
					 | 
				
			||||||
PFN_vkCmdEndRendering vk_cmd_end_rendering {};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
PFN_vkGetPhysicalDeviceSurfaceSupportKHR vk_get_physical_device_surface_support {};
 | 
					PFN_vkGetPhysicalDeviceSurfaceSupportKHR vk_get_physical_device_surface_support {};
 | 
				
			||||||
PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vk_get_physical_device_surface_capabilities {};
 | 
					PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vk_get_physical_device_surface_capabilities {};
 | 
				
			||||||
PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vk_get_physical_device_surface_formats {};
 | 
					PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vk_get_physical_device_surface_formats {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
auto vk_create_xlib_surface_khr = PFN_vkCreateXlibSurfaceKHR {};
 | 
					auto vk_create_xlib_surface_khr = PFN_vkCreateXlibSurfaceKHR {};
 | 
				
			||||||
auto vk_destroy_surface_khr = PFN_vkDestroySurfaceKHR {};
 | 
					auto vk_destroy_surface_khr = PFN_vkDestroySurfaceKHR {};
 | 
				
			||||||
 | 
					 | 
				
			||||||
// NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables)
 | 
					// NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Instance::Instance()
 | 
					Instance::Instance()
 | 
				
			||||||
| 
						 | 
					@ -150,7 +127,6 @@ void Instance::initialize_instance()
 | 
				
			||||||
		VK_EXT_DEBUG_UTILS_EXTENSION_NAME,
 | 
							VK_EXT_DEBUG_UTILS_EXTENSION_NAME,
 | 
				
			||||||
		VK_KHR_SURFACE_EXTENSION_NAME,
 | 
							VK_KHR_SURFACE_EXTENSION_NAME,
 | 
				
			||||||
		VK_KHR_XLIB_SURFACE_EXTENSION_NAME,
 | 
							VK_KHR_XLIB_SURFACE_EXTENSION_NAME,
 | 
				
			||||||
		VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME,
 | 
					 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const char *layer_name = "VK_LAYER_KHRONOS_validation";
 | 
						const char *layer_name = "VK_LAYER_KHRONOS_validation";
 | 
				
			||||||
| 
						 | 
					@ -322,7 +298,6 @@ void Instance::load_instance_functions()
 | 
				
			||||||
	load_fn(vk_destroy_device, "vkDestroyDevice");
 | 
						load_fn(vk_destroy_device, "vkDestroyDevice");
 | 
				
			||||||
	load_fn(vk_get_physical_device_features, "vkGetPhysicalDeviceFeatures");
 | 
						load_fn(vk_get_physical_device_features, "vkGetPhysicalDeviceFeatures");
 | 
				
			||||||
	load_fn(vk_enumerate_device_extension_properties, "vkEnumerateDeviceExtensionProperties");
 | 
						load_fn(vk_enumerate_device_extension_properties, "vkEnumerateDeviceExtensionProperties");
 | 
				
			||||||
	load_fn(vk_get_physical_device_memory_properties, "vkGetPhysicalDeviceMemoryProperties");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	load_fn(vk_cmd_begin_debug_label, "vkCmdBeginDebugUtilsLabelEXT");
 | 
						load_fn(vk_cmd_begin_debug_label, "vkCmdBeginDebugUtilsLabelEXT");
 | 
				
			||||||
	load_fn(vk_cmd_end_debug_label, "vkCmdEndDebugUtilsLabelEXT");
 | 
						load_fn(vk_cmd_end_debug_label, "vkCmdEndDebugUtilsLabelEXT");
 | 
				
			||||||
| 
						 | 
					@ -395,26 +370,7 @@ void Instance::load_device_functions_impl(VkDevice device)
 | 
				
			||||||
	load_fn(vk_cmd_draw, "vkCmdDraw");
 | 
						load_fn(vk_cmd_draw, "vkCmdDraw");
 | 
				
			||||||
	load_fn(vk_cmd_set_viewport, "vkCmdSetViewport");
 | 
						load_fn(vk_cmd_set_viewport, "vkCmdSetViewport");
 | 
				
			||||||
	load_fn(vk_cmd_set_scissors, "vkCmdSetScissor");
 | 
						load_fn(vk_cmd_set_scissors, "vkCmdSetScissor");
 | 
				
			||||||
	load_fn(vk_cmd_push_constants, "vkCmdPushConstants");
 | 
					 | 
				
			||||||
	load_fn(vk_cmd_copy_buffer, "vkCmdCopyBuffer");
 | 
					 | 
				
			||||||
	load_fn(vk_create_descriptor_set_layout, "vkCreateDescriptorSetLayout");
 | 
					 | 
				
			||||||
	load_fn(vk_destroy_descriptor_set_layout, "vkDestroyDescriptorSetLayout");
 | 
					 | 
				
			||||||
	load_fn(vk_create_descriptor_pool, "vkCreateDescriptorPool");
 | 
					 | 
				
			||||||
	load_fn(vk_destroy_descriptor_pool, "vkDestroyDescriptorPool");
 | 
					 | 
				
			||||||
	load_fn(vk_allocate_descriptor_sets, "vkAllocateDescriptorSets");
 | 
					 | 
				
			||||||
	load_fn(vk_free_descriptor_sets, "vkFreeDescriptorSets");
 | 
					 | 
				
			||||||
	load_fn(vk_create_buffer, "vkCreateBuffer");
 | 
					 | 
				
			||||||
	load_fn(vk_destroy_buffer, "vkDestroyBuffer");
 | 
					 | 
				
			||||||
	load_fn(vk_allocate_memory, "vkAllocateMemory");
 | 
					 | 
				
			||||||
	load_fn(vk_bind_buffer_memory, "vkBindBufferMemory");
 | 
					 | 
				
			||||||
	load_fn(vk_map_memory, "vkMapMemory");
 | 
					 | 
				
			||||||
	load_fn(vk_unmap_memory, "vkUnmapMemory");
 | 
					 | 
				
			||||||
	load_fn(vk_free_memory, "vkFreeMemory");
 | 
					 | 
				
			||||||
	load_fn(vk_get_buffer_memory_requirements, "vkGetBufferMemoryRequirements");
 | 
					 | 
				
			||||||
	load_fn(vk_reset_command_buffer, "vkResetCommandBuffer");
 | 
						load_fn(vk_reset_command_buffer, "vkResetCommandBuffer");
 | 
				
			||||||
 | 
					 | 
				
			||||||
	load_fn(vk_cmd_begin_rendering, "vkCmdBeginRendering");
 | 
					 | 
				
			||||||
	load_fn(vk_cmd_end_rendering, "vkCmdEndRendering");
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
auto Instance::enumerate_gpus() const -> std::vector<VkPhysicalDevice>
 | 
					auto Instance::enumerate_gpus() const -> std::vector<VkPhysicalDevice>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -49,17 +49,6 @@ public:
 | 
				
			||||||
		return m_images.size();
 | 
							return m_images.size();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] auto get_image_view(uint32_t idx) -> VkImageView
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		return m_image_views[idx];
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	[[nodiscard]] auto get_image(uint32_t idx) -> VkImage
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		return m_images[idx];
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	[[nodiscard]] auto create_framebuffers_for_pass(VkRenderPass pass) const
 | 
						[[nodiscard]] auto create_framebuffers_for_pass(VkRenderPass pass) const
 | 
				
			||||||
	    -> std::vector<VkFramebuffer>;
 | 
						    -> std::vector<VkFramebuffer>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,106 +0,0 @@
 | 
				
			||||||
#include <renderer/backend/vk/context/device.hpp>
 | 
					 | 
				
			||||||
#include <renderer/backend/vk/context/gpu.hpp>
 | 
					 | 
				
			||||||
#include <renderer/backend/vk/data/buffer.hpp>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace lt::renderer::vk {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Buffer::Buffer(IDevice *device, IGpu *gpu, const CreateInfo &info)
 | 
					 | 
				
			||||||
    : m_device(static_cast<Device *>(device))
 | 
					 | 
				
			||||||
    , m_gpu(static_cast<Gpu *>(gpu))
 | 
					 | 
				
			||||||
    , m_buffer(
 | 
					 | 
				
			||||||
          m_device,
 | 
					 | 
				
			||||||
          VkBufferCreateInfo {
 | 
					 | 
				
			||||||
              .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
 | 
					 | 
				
			||||||
              .size = info.size,
 | 
					 | 
				
			||||||
              .usage = to_native_usage_flags(info.usage),
 | 
					 | 
				
			||||||
              .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
      )
 | 
					 | 
				
			||||||
    , m_memory(m_device, m_buffer, determine_allocation_info(info.usage))
 | 
					 | 
				
			||||||
    , m_size(info.size)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[nodiscard]] auto Buffer::map() -> std::span<std::byte> /* override */
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return m_device->map_memory(m_memory, m_size, 0ul);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void Buffer::unmap() /* override */
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	m_device->unmap_memory(m_memory);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[nodiscard]] auto Buffer::determine_allocation_info(Usage usage) const -> VkMemoryAllocateInfo
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	const auto requirements = m_device->get_memory_requirements(m_buffer);
 | 
					 | 
				
			||||||
	auto memory_properties = m_gpu->get_memory_properties();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	const auto required_properties = to_native_memory_properties(usage);
 | 
					 | 
				
			||||||
	auto type = 0u;
 | 
					 | 
				
			||||||
	for (auto idx = 0; idx < memory_properties.memoryTypeCount; ++idx)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		const auto property_flags = memory_properties.memoryTypes[idx].propertyFlags;
 | 
					 | 
				
			||||||
		if (has_correct_memory_type_bit(requirements.memoryTypeBits, idx)
 | 
					 | 
				
			||||||
		    && has_required_memory_properties(required_properties, property_flags))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			type = idx;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return VkMemoryAllocateInfo {
 | 
					 | 
				
			||||||
		.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
 | 
					 | 
				
			||||||
		.allocationSize = requirements.size,
 | 
					 | 
				
			||||||
		.memoryTypeIndex = type,
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[nodiscard]] auto Buffer::to_native_usage_flags(Usage usage) const -> VkBufferUsageFlags
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	switch (usage)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	case Usage::vertex: return VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case Usage::index: return VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case Usage::storage:
 | 
					 | 
				
			||||||
		return VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case Usage::staging: return VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	std::unreachable();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[nodiscard]] auto Buffer::to_native_memory_properties(Usage usage) const -> VkMemoryPropertyFlags
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	switch (usage)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	case Usage::vertex:
 | 
					 | 
				
			||||||
	case Usage::index:
 | 
					 | 
				
			||||||
	case Usage::storage: return VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	case Usage::staging:
 | 
					 | 
				
			||||||
		return VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	std::unreachable();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[nodiscard]] auto Buffer::has_correct_memory_type_bit(uint32_t type_bits, uint32_t type_idx) const
 | 
					 | 
				
			||||||
    -> bool
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return type_bits & (1 << type_idx);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[nodiscard]] auto Buffer::has_required_memory_properties(
 | 
					 | 
				
			||||||
    uint32_t required_properties,
 | 
					 | 
				
			||||||
    uint32_t property_flags
 | 
					 | 
				
			||||||
) const -> bool
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return (property_flags & required_properties) == required_properties;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} // namespace lt::renderer::vk
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,60 +0,0 @@
 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <renderer/backend/vk/raii/raii.hpp>
 | 
					 | 
				
			||||||
#include <renderer/frontend/data/buffer.hpp>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace lt::renderer::vk {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Buffer: public IBuffer
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
	Buffer(class IDevice *device, class IGpu *gpu, const CreateInfo &info);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	[[nodiscard]] auto map() -> std::span<std::byte> override;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void unmap() override;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// TODO(Light): this is to make copying possible.
 | 
					 | 
				
			||||||
	// But it should be removed in the future,
 | 
					 | 
				
			||||||
	// Right now it's not possible because: buffers can't understand CommandBuffers.
 | 
					 | 
				
			||||||
	// And I'm not sure how to properly abstract over command buffers,
 | 
					 | 
				
			||||||
	// before using other APIs...
 | 
					 | 
				
			||||||
	[[nodiscard]] auto vk()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		return *m_buffer;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	[[nodiscard]] auto get_size() const -> size_t override
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		return m_size;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
private:
 | 
					 | 
				
			||||||
	[[nodiscard]] auto determine_allocation_info(Usage usage) const -> VkMemoryAllocateInfo;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	[[nodiscard]] auto to_native_usage_flags(Usage usage) const -> VkBufferUsageFlags;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	[[nodiscard]] auto to_native_memory_properties(Usage usage) const -> VkMemoryPropertyFlags;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	[[nodiscard]] auto has_correct_memory_type_bit(uint32_t type_bits, uint32_t type_idx) const
 | 
					 | 
				
			||||||
	    -> bool;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	[[nodiscard]] auto has_required_memory_properties(
 | 
					 | 
				
			||||||
	    uint32_t required_properties,
 | 
					 | 
				
			||||||
	    uint32_t property_flags
 | 
					 | 
				
			||||||
	) const -> bool;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Device *m_device {};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Gpu *m_gpu {};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	raii::Buffer m_buffer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	raii::Memory m_memory;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// TODO(Light): should this reflect the allocation size instead?
 | 
					 | 
				
			||||||
	size_t m_size {};
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} // namespace lt::renderer::vk
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,11 +1,10 @@
 | 
				
			||||||
#include <memory/pointer_types/null_on_move.hpp>
 | 
					#include <memory/pointer_types/null_on_move.hpp>
 | 
				
			||||||
#include <renderer/backend/vk/context/device.hpp>
 | 
					 | 
				
			||||||
#include <renderer/backend/vk/context/instance.hpp>
 | 
					#include <renderer/backend/vk/context/instance.hpp>
 | 
				
			||||||
#include <renderer/backend/vk/vulkan.hpp>
 | 
					#include <renderer/backend/vk/vulkan.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace lt::renderer::vk::raii {
 | 
					namespace lt::renderer::vk::raii {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NOLINTNEXTLINE(cppcoreguidelines-special-member-functions)
 | 
				
			||||||
class DebugMessenger
 | 
					class DebugMessenger
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
| 
						 | 
					@ -17,108 +16,18 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	~DebugMessenger()
 | 
						~DebugMessenger()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		if (m_instance)
 | 
							if (!m_instance)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			m_instance->destroy_messenger(m_object);
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							m_instance->destroy_messenger(m_object);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	DebugMessenger(DebugMessenger &&) = default;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	DebugMessenger(const DebugMessenger &) = delete;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	auto operator=(DebugMessenger &&) -> DebugMessenger & = default;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	auto operator=(const DebugMessenger &) -> DebugMessenger & = delete;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	memory::NullOnMove<Instance *> m_instance {};
 | 
						memory::NullOnMove<Instance *> m_instance {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	VkDebugUtilsMessengerEXT m_object;
 | 
						VkDebugUtilsMessengerEXT m_object;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Buffer
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
	Buffer(Device *device, VkBufferCreateInfo info)
 | 
					 | 
				
			||||||
	    : m_device(device)
 | 
					 | 
				
			||||||
	    , m_object(m_device->create_buffer(info))
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	~Buffer()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (m_device)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			m_device->destroy_buffer(m_object);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Buffer(Buffer &&) = default;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Buffer(const Buffer &) = delete;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	auto operator=(Buffer &&) -> Buffer & = default;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	auto operator=(const Buffer &) -> Buffer & = delete;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	[[nodiscard]] auto operator*() const -> VkBuffer
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		return m_object;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	[[nodiscard]] operator VkBuffer() const
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		return m_object;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
private:
 | 
					 | 
				
			||||||
	memory::NullOnMove<Device *> m_device {};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	VkBuffer m_object;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Memory
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
	Memory(Device *device, VkBuffer buffer, VkMemoryAllocateInfo info)
 | 
					 | 
				
			||||||
	    : m_device(device)
 | 
					 | 
				
			||||||
	    , m_object(m_device->allocate_memory(info))
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		m_device->bind_memory(buffer, m_object);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	~Memory()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (m_device)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			m_device->free_memory(m_object);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Memory(Memory &&) = default;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Memory(const Memory &) = delete;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	auto operator=(Memory &&) -> Memory & = default;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	auto operator=(const Memory &) -> Memory & = delete;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	[[nodiscard]] auto operator*() const -> VkDeviceMemory
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		return m_object;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	[[nodiscard]] operator VkDeviceMemory() const
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		return m_object;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
private:
 | 
					 | 
				
			||||||
	memory::NullOnMove<Device *> m_device {};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	VkDeviceMemory m_object = VK_NULL_HANDLE;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} // namespace lt::renderer::vk::raii
 | 
					} // namespace lt::renderer::vk::raii
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,6 @@
 | 
				
			||||||
#include <renderer/backend/vk/context/device.hpp>
 | 
					#include <renderer/backend/vk/context/device.hpp>
 | 
				
			||||||
#include <renderer/backend/vk/context/swapchain.hpp>
 | 
					#include <renderer/backend/vk/context/swapchain.hpp>
 | 
				
			||||||
#include <renderer/backend/vk/renderer/pass.hpp>
 | 
					#include <renderer/backend/vk/renderer/pass.hpp>
 | 
				
			||||||
#include <renderer/data/frame_constants.hpp>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace lt::renderer::vk {
 | 
					namespace lt::renderer::vk {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,12 +12,12 @@ Pass::Pass(
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
    : m_device(static_cast<Device *>(device))
 | 
					    : m_device(static_cast<Device *>(device))
 | 
				
			||||||
    , m_layout(m_device->create_pipeline_layout(
 | 
					    , m_layout(m_device->create_pipeline_layout(
 | 
				
			||||||
          std::vector<VkPushConstantRange> {
 | 
					          VkPipelineLayoutCreateInfo {
 | 
				
			||||||
              VkPushConstantRange {
 | 
					              .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
 | 
				
			||||||
                  .stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
 | 
					              .setLayoutCount = 0u,
 | 
				
			||||||
                  .offset = 0u,
 | 
					              .pSetLayouts = nullptr,
 | 
				
			||||||
                  .size = sizeof(FrameConstants),
 | 
					              .pushConstantRangeCount = 0u,
 | 
				
			||||||
              },
 | 
					              .pPushConstantRanges = nullptr,
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
      ))
 | 
					      ))
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -113,16 +112,17 @@ Pass::Pass(
 | 
				
			||||||
		.blendConstants = { 0.0f, 0.0, 0.0, 0.0 },
 | 
							.blendConstants = { 0.0f, 0.0, 0.0, 0.0 },
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// auto attachment_description = VkAttachmentDescription {
 | 
					
 | 
				
			||||||
	// 	.format =,
 | 
						auto attachment_description = VkAttachmentDescription {
 | 
				
			||||||
	// 	.samples = VK_SAMPLE_COUNT_1_BIT,
 | 
							.format = static_cast<Swapchain *>(swapchain)->get_format(),
 | 
				
			||||||
	// 	.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
 | 
							.samples = VK_SAMPLE_COUNT_1_BIT,
 | 
				
			||||||
	// 	.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
 | 
							.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
 | 
				
			||||||
	// 	.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
 | 
							.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
 | 
				
			||||||
	// 	.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
 | 
							.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
 | 
				
			||||||
	// 	.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
 | 
							.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
 | 
				
			||||||
	// 	.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
 | 
							.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
 | 
				
			||||||
	// };
 | 
							.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto color_attachment_ref = VkAttachmentReference {
 | 
						auto color_attachment_ref = VkAttachmentReference {
 | 
				
			||||||
		.attachment = 0,
 | 
							.attachment = 0,
 | 
				
			||||||
| 
						 | 
					@ -144,18 +144,21 @@ Pass::Pass(
 | 
				
			||||||
		.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
 | 
							.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto color_format = static_cast<Swapchain *>(swapchain)->get_format();
 | 
						m_pass = m_device->create_pass(
 | 
				
			||||||
	auto rendering_info = VkPipelineRenderingCreateInfoKHR {
 | 
						    VkRenderPassCreateInfo {
 | 
				
			||||||
		.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
 | 
						        .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
 | 
				
			||||||
		.colorAttachmentCount = 1u,
 | 
						        .attachmentCount = 1u,
 | 
				
			||||||
		.pColorAttachmentFormats = &color_format,
 | 
						        .pAttachments = &attachment_description,
 | 
				
			||||||
 | 
						        .subpassCount = 1u,
 | 
				
			||||||
	};
 | 
						        .pSubpasses = &subpass_description,
 | 
				
			||||||
 | 
						        .dependencyCount = 1u,
 | 
				
			||||||
 | 
						        .pDependencies = &pass_dependency,
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
 | 
						);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	m_pipeline = m_device->create_graphics_pipeline(
 | 
						m_pipeline = m_device->create_graphics_pipeline(
 | 
				
			||||||
	    VkGraphicsPipelineCreateInfo {
 | 
						    VkGraphicsPipelineCreateInfo {
 | 
				
			||||||
	        .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
 | 
						        .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
 | 
				
			||||||
	        .pNext = &rendering_info,
 | 
					 | 
				
			||||||
	        .stageCount = static_cast<uint32_t>(shader_stages.size()),
 | 
						        .stageCount = static_cast<uint32_t>(shader_stages.size()),
 | 
				
			||||||
	        .pStages = shader_stages.data(),
 | 
						        .pStages = shader_stages.data(),
 | 
				
			||||||
	        .pVertexInputState = &vertex_input,
 | 
						        .pVertexInputState = &vertex_input,
 | 
				
			||||||
| 
						 | 
					@ -167,14 +170,15 @@ Pass::Pass(
 | 
				
			||||||
	        .pColorBlendState = &color_blend,
 | 
						        .pColorBlendState = &color_blend,
 | 
				
			||||||
	        .pDynamicState = &dynamic_state,
 | 
						        .pDynamicState = &dynamic_state,
 | 
				
			||||||
	        .layout = m_layout,
 | 
						        .layout = m_layout,
 | 
				
			||||||
	        .renderPass = VK_NULL_HANDLE,
 | 
						        .renderPass = m_pass,
 | 
				
			||||||
	        .subpass = 0u,
 | 
						        .subpass = 0u,
 | 
				
			||||||
	        .basePipelineHandle = VK_NULL_HANDLE,
 | 
						        .basePipelineHandle = VK_NULL_HANDLE,
 | 
				
			||||||
	        .basePipelineIndex = -1,
 | 
						        .basePipelineIndex = -1,
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
	);
 | 
						);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// m_framebuffers = static_cast<Swapchain *>(swapchain)->create_framebuffers_for_pass(m_pass);
 | 
						m_framebuffers = static_cast<Swapchain *>(swapchain)->create_framebuffers_for_pass(m_pass);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	m_device->destroy_shader_module(vertex_module);
 | 
						m_device->destroy_shader_module(vertex_module);
 | 
				
			||||||
	m_device->destroy_shader_module(fragment_module);
 | 
						m_device->destroy_shader_module(fragment_module);
 | 
				
			||||||
| 
						 | 
					@ -190,7 +194,7 @@ Pass::~Pass()
 | 
				
			||||||
	m_device->wait_idle();
 | 
						m_device->wait_idle();
 | 
				
			||||||
	m_device->destroy_framebuffers(m_framebuffers);
 | 
						m_device->destroy_framebuffers(m_framebuffers);
 | 
				
			||||||
	m_device->destroy_pipeline(m_pipeline);
 | 
						m_device->destroy_pipeline(m_pipeline);
 | 
				
			||||||
	// m_device->destroy_pass(m_pass);
 | 
						m_device->destroy_pass(m_pass);
 | 
				
			||||||
	m_device->destroy_pipeline_layout(m_layout);
 | 
						m_device->destroy_pipeline_layout(m_layout);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -203,8 +207,7 @@ void Pass::replace_swapchain(const ISwapchain &swapchain)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	m_device->wait_idle();
 | 
						m_device->wait_idle();
 | 
				
			||||||
	m_device->destroy_framebuffers(m_framebuffers);
 | 
						m_device->destroy_framebuffers(m_framebuffers);
 | 
				
			||||||
	// m_framebuffers = static_cast<const Swapchain
 | 
						m_framebuffers = static_cast<const Swapchain &>(swapchain).create_framebuffers_for_pass(m_pass);
 | 
				
			||||||
	// &>(swapchain).create_framebuffers_for_pass(m_pass);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
auto Pass::create_module(lt::assets::Blob blob) -> VkShaderModule
 | 
					auto Pass::create_module(lt::assets::Blob blob) -> VkShaderModule
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,16 +29,16 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void replace_swapchain(const ISwapchain &swapchain);
 | 
						void replace_swapchain(const ISwapchain &swapchain);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						[[nodiscard]] auto get_pass() -> VkRenderPass
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return m_pass;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] auto get_pipeline() -> VkPipeline
 | 
						[[nodiscard]] auto get_pipeline() -> VkPipeline
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return m_pipeline;
 | 
							return m_pipeline;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] auto get_layout() -> VkPipelineLayout
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		return m_layout;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	[[nodiscard]] auto get_framebuffers() -> std::vector<VkFramebuffer> &
 | 
						[[nodiscard]] auto get_framebuffers() -> std::vector<VkFramebuffer> &
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return m_framebuffers;
 | 
							return m_framebuffers;
 | 
				
			||||||
| 
						 | 
					@ -49,6 +49,8 @@ private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memory::NullOnMove<class Device *> m_device {};
 | 
						memory::NullOnMove<class Device *> m_device {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						VkRenderPass m_pass = VK_NULL_HANDLE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	VkPipeline m_pipeline = VK_NULL_HANDLE;
 | 
						VkPipeline m_pipeline = VK_NULL_HANDLE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	VkPipelineLayout m_layout = VK_NULL_HANDLE;
 | 
						VkPipelineLayout m_layout = VK_NULL_HANDLE;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -100,7 +100,6 @@ Renderer::~Renderer()
 | 
				
			||||||
	vk_reset_command_buffer(cmd, {});
 | 
						vk_reset_command_buffer(cmd, {});
 | 
				
			||||||
	record_cmd(cmd, *image_idx);
 | 
						record_cmd(cmd, *image_idx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
	auto wait_stage = VkPipelineStageFlags { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
 | 
						auto wait_stage = VkPipelineStageFlags { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
 | 
				
			||||||
	auto &submit_semaphore = m_submit_semaphores[*image_idx];
 | 
						auto &submit_semaphore = m_submit_semaphores[*image_idx];
 | 
				
			||||||
	m_device->submit(
 | 
						m_device->submit(
 | 
				
			||||||
| 
						 | 
					@ -143,52 +142,35 @@ void Renderer::replace_swapchain(ISwapchain *swapchain)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Renderer::record_cmd(VkCommandBuffer cmd, uint32_t image_idx)
 | 
					void Renderer::record_cmd(VkCommandBuffer cmd, uint32_t image_idx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const auto cmd_begin_info = VkCommandBufferBeginInfo {
 | 
						auto cmd_begin_info = VkCommandBufferBeginInfo {
 | 
				
			||||||
		.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
 | 
							.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
 | 
				
			||||||
		.flags = {},
 | 
							.flags = {},
 | 
				
			||||||
		.pInheritanceInfo = nullptr,
 | 
							.pInheritanceInfo = nullptr,
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const auto begin_frame_barrier = VkImageMemoryBarrier {
 | 
						vkc(vk_begin_command_buffer(cmd, &cmd_begin_info));
 | 
				
			||||||
		.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
 | 
					 | 
				
			||||||
		.srcAccessMask = {},
 | 
					 | 
				
			||||||
		.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
 | 
					 | 
				
			||||||
		.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
 | 
					 | 
				
			||||||
		.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
 | 
					 | 
				
			||||||
        .image = m_swapchain->get_image(image_idx),
 | 
					 | 
				
			||||||
        .subresourceRange = VkImageSubresourceRange{
 | 
					 | 
				
			||||||
            .aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT,
 | 
					 | 
				
			||||||
            .baseMipLevel   = 0u,
 | 
					 | 
				
			||||||
            .levelCount     = VK_REMAINING_MIP_LEVELS,
 | 
					 | 
				
			||||||
            .baseArrayLayer = 0u,
 | 
					 | 
				
			||||||
            .layerCount     = VK_REMAINING_ARRAY_LAYERS,
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto clear_value = VkClearValue {
 | 
				
			||||||
 | 
								.color = { 
 | 
				
			||||||
 | 
					                0.93,
 | 
				
			||||||
 | 
					                0.93,
 | 
				
			||||||
 | 
					                0.93,
 | 
				
			||||||
 | 
					               1.0,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto pass_begin_info = VkRenderPassBeginInfo {
 | 
				
			||||||
 | 
							.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
 | 
				
			||||||
 | 
							.renderPass = m_pass->get_pass(),
 | 
				
			||||||
 | 
							.framebuffer = m_pass->get_framebuffers()[image_idx],
 | 
				
			||||||
 | 
							.renderArea = { .offset = {}, .extent = m_resolution },
 | 
				
			||||||
 | 
							.clearValueCount = 1u,
 | 
				
			||||||
 | 
							.pClearValues = &clear_value
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
						vk_cmd_begin_render_pass(cmd, &pass_begin_info, VK_SUBPASS_CONTENTS_INLINE);
 | 
				
			||||||
 | 
						vk_cmd_bind_pipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pass->get_pipeline());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const auto end_frame_barrier = VkImageMemoryBarrier {
 | 
						auto viewport = VkViewport {
 | 
				
			||||||
		.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
 | 
					 | 
				
			||||||
		.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
 | 
					 | 
				
			||||||
		.dstAccessMask = {},
 | 
					 | 
				
			||||||
		.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
 | 
					 | 
				
			||||||
		.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
 | 
					 | 
				
			||||||
        .image = m_swapchain->get_image(image_idx),
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        .subresourceRange = VkImageSubresourceRange{
 | 
					 | 
				
			||||||
            .aspectMask     = VK_IMAGE_ASPECT_COLOR_BIT,
 | 
					 | 
				
			||||||
            .baseMipLevel   = 0u,
 | 
					 | 
				
			||||||
            .levelCount     = VK_REMAINING_MIP_LEVELS,
 | 
					 | 
				
			||||||
            .baseArrayLayer = 0u,
 | 
					 | 
				
			||||||
            .layerCount     = VK_REMAINING_ARRAY_LAYERS,
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	const auto scissor = VkRect2D {
 | 
					 | 
				
			||||||
		.offset = { .x = 0u, .y = 0u },
 | 
					 | 
				
			||||||
		.extent = m_resolution,
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	const auto viewport = VkViewport {
 | 
					 | 
				
			||||||
		.x = 0.0f,
 | 
							.x = 0.0f,
 | 
				
			||||||
		.y = 0.0f,
 | 
							.y = 0.0f,
 | 
				
			||||||
		.width = static_cast<float>(m_resolution.width),
 | 
							.width = static_cast<float>(m_resolution.width),
 | 
				
			||||||
| 
						 | 
					@ -196,70 +178,17 @@ void Renderer::record_cmd(VkCommandBuffer cmd, uint32_t image_idx)
 | 
				
			||||||
		.minDepth = 0.0f,
 | 
							.minDepth = 0.0f,
 | 
				
			||||||
		.maxDepth = 1.0f,
 | 
							.maxDepth = 1.0f,
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					 | 
				
			||||||
	const auto color_attachment_info = VkRenderingAttachmentInfoKHR {
 | 
					 | 
				
			||||||
		.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO,
 | 
					 | 
				
			||||||
		.imageView = m_swapchain->get_image_view(image_idx),
 | 
					 | 
				
			||||||
		.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
 | 
					 | 
				
			||||||
		.resolveMode = VK_RESOLVE_MODE_NONE,
 | 
					 | 
				
			||||||
		.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
 | 
					 | 
				
			||||||
		.storeOp = VK_ATTACHMENT_STORE_OP_STORE,
 | 
					 | 
				
			||||||
		.clearValue = VkClearValue { .color = { 0.93, 0.93, 0.93, 1.0 } },
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	const auto rendering_info = VkRenderingInfoKHR {
 | 
					 | 
				
			||||||
		.sType = VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
 | 
					 | 
				
			||||||
		.renderArea = scissor,
 | 
					 | 
				
			||||||
		.layerCount = 1,
 | 
					 | 
				
			||||||
		.colorAttachmentCount = 1,
 | 
					 | 
				
			||||||
		.pColorAttachments = &color_attachment_info,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	vkc(vk_begin_command_buffer(cmd, &cmd_begin_info));
 | 
					 | 
				
			||||||
	vk_cmd_push_constants(
 | 
					 | 
				
			||||||
	    cmd,
 | 
					 | 
				
			||||||
	    m_pass->get_layout(),
 | 
					 | 
				
			||||||
	    VK_SHADER_STAGE_VERTEX_BIT,
 | 
					 | 
				
			||||||
	    0u,
 | 
					 | 
				
			||||||
	    sizeof(FrameConstants),
 | 
					 | 
				
			||||||
	    &m_frame_constants
 | 
					 | 
				
			||||||
	);
 | 
					 | 
				
			||||||
	vk_cmd_pipeline_barrier(
 | 
					 | 
				
			||||||
	    cmd,
 | 
					 | 
				
			||||||
	    VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
 | 
					 | 
				
			||||||
	    VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
 | 
					 | 
				
			||||||
	    0,
 | 
					 | 
				
			||||||
	    0,
 | 
					 | 
				
			||||||
	    nullptr,
 | 
					 | 
				
			||||||
	    0,
 | 
					 | 
				
			||||||
	    nullptr,
 | 
					 | 
				
			||||||
	    1,
 | 
					 | 
				
			||||||
	    &begin_frame_barrier
 | 
					 | 
				
			||||||
	);
 | 
					 | 
				
			||||||
	vk_cmd_begin_rendering(cmd, &rendering_info);
 | 
					 | 
				
			||||||
	vk_cmd_bind_pipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pass->get_pipeline());
 | 
					 | 
				
			||||||
	vk_cmd_set_viewport(cmd, 0, 1, &viewport);
 | 
						vk_cmd_set_viewport(cmd, 0, 1, &viewport);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto scissor = VkRect2D {
 | 
				
			||||||
 | 
							.offset = { 0u, 0u },
 | 
				
			||||||
 | 
							.extent = m_resolution,
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
	vk_cmd_set_scissors(cmd, 0, 1, &scissor);
 | 
						vk_cmd_set_scissors(cmd, 0, 1, &scissor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	vk_cmd_draw(cmd, 3, 1, 0, 0);
 | 
						vk_cmd_draw(cmd, 3, 1, 0, 0);
 | 
				
			||||||
	vk_cmd_end_rendering(cmd);
 | 
						vk_cmd_end_render_pass(cmd);
 | 
				
			||||||
	vk_cmd_pipeline_barrier(
 | 
					 | 
				
			||||||
	    cmd,
 | 
					 | 
				
			||||||
	    VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
 | 
					 | 
				
			||||||
	    VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
 | 
					 | 
				
			||||||
	    0,
 | 
					 | 
				
			||||||
	    0,
 | 
					 | 
				
			||||||
	    nullptr,
 | 
					 | 
				
			||||||
	    0,
 | 
					 | 
				
			||||||
	    nullptr,
 | 
					 | 
				
			||||||
	    1,
 | 
					 | 
				
			||||||
	    &end_frame_barrier
 | 
					 | 
				
			||||||
	);
 | 
					 | 
				
			||||||
	vkc(vk_end_command_buffer(cmd));
 | 
						vkc(vk_end_command_buffer(cmd));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void submit_sprite(const components::Sprite &sprite, const math::components::Transform &transform)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} // namespace lt::renderer::vk
 | 
					} // namespace lt::renderer::vk
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,10 +3,8 @@
 | 
				
			||||||
#include <memory/reference.hpp>
 | 
					#include <memory/reference.hpp>
 | 
				
			||||||
#include <ranges>
 | 
					#include <ranges>
 | 
				
			||||||
#include <renderer/backend/vk/context/device.hpp>
 | 
					#include <renderer/backend/vk/context/device.hpp>
 | 
				
			||||||
#include <renderer/backend/vk/data/buffer.hpp>
 | 
					 | 
				
			||||||
#include <renderer/backend/vk/renderer/pass.hpp>
 | 
					#include <renderer/backend/vk/renderer/pass.hpp>
 | 
				
			||||||
#include <renderer/backend/vk/utils.hpp>
 | 
					#include <renderer/backend/vk/utils.hpp>
 | 
				
			||||||
#include <renderer/frontend/data/buffer.hpp>
 | 
					 | 
				
			||||||
#include <renderer/frontend/renderer/pass.hpp>
 | 
					#include <renderer/frontend/renderer/pass.hpp>
 | 
				
			||||||
#include <renderer/frontend/renderer/renderer.hpp>
 | 
					#include <renderer/frontend/renderer/renderer.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,18 +29,6 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void replace_swapchain(ISwapchain *swapchain) override;
 | 
						void replace_swapchain(ISwapchain *swapchain) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void set_frame_constants(FrameConstants constants) override
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		m_frame_constants = constants;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void submit_sprite(
 | 
					 | 
				
			||||||
	    const components::Sprite &sprite,
 | 
					 | 
				
			||||||
	    const math::components::Transform &transform
 | 
					 | 
				
			||||||
	) override
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	void record_cmd(VkCommandBuffer cmd, uint32_t image_idx);
 | 
						void record_cmd(VkCommandBuffer cmd, uint32_t image_idx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -65,8 +51,6 @@ private:
 | 
				
			||||||
	VkExtent2D m_resolution;
 | 
						VkExtent2D m_resolution;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint32_t m_max_frames_in_flight {};
 | 
						uint32_t m_max_frames_in_flight {};
 | 
				
			||||||
 | 
					 | 
				
			||||||
	FrameConstants m_frame_constants;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace lt::renderer::vk
 | 
					} // namespace lt::renderer::vk
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										18
									
								
								modules/renderer/private/backend/vk/test_utils.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								modules/renderer/private/backend/vk/test_utils.hpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,18 @@
 | 
				
			||||||
 | 
					// template<>
 | 
				
			||||||
 | 
					// struct std::formatter<VkExtent2D>
 | 
				
			||||||
 | 
					// {
 | 
				
			||||||
 | 
					// 	constexpr auto parse(std::format_parse_context &context)
 | 
				
			||||||
 | 
					// 	{
 | 
				
			||||||
 | 
					// 		return context.begin();
 | 
				
			||||||
 | 
					// 	}
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 	auto format(const VkExtent2D &val, std::format_context &context) const
 | 
				
			||||||
 | 
					// 	{
 | 
				
			||||||
 | 
					// 		return std::format_to(context.out(), "{}, {}", val.width, val.height);
 | 
				
			||||||
 | 
					// 	}
 | 
				
			||||||
 | 
					// };
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// inline auto operator==(VkExtent2D lhs, VkExtent2D rhs) -> bool
 | 
				
			||||||
 | 
					// {
 | 
				
			||||||
 | 
					// 	return lhs.width == rhs.width && lhs.height == rhs.height;
 | 
				
			||||||
 | 
					// }
 | 
				
			||||||
| 
						 | 
					@ -13,9 +13,8 @@ extern PFN_vkGetPhysicalDeviceQueueFamilyProperties vk_get_physical_device_queue
 | 
				
			||||||
extern PFN_vkCreateDevice vk_create_device;
 | 
					extern PFN_vkCreateDevice vk_create_device;
 | 
				
			||||||
extern PFN_vkGetDeviceProcAddr vk_get_device_proc_address;
 | 
					extern PFN_vkGetDeviceProcAddr vk_get_device_proc_address;
 | 
				
			||||||
extern PFN_vkDestroyDevice vk_destroy_device;
 | 
					extern PFN_vkDestroyDevice vk_destroy_device;
 | 
				
			||||||
extern PFN_vkGetPhysicalDeviceFeatures2 vk_get_physical_device_features;
 | 
					extern PFN_vkGetPhysicalDeviceFeatures vk_get_physical_device_features;
 | 
				
			||||||
extern PFN_vkEnumerateDeviceExtensionProperties vk_enumerate_device_extension_properties;
 | 
					extern PFN_vkEnumerateDeviceExtensionProperties vk_enumerate_device_extension_properties;
 | 
				
			||||||
extern PFN_vkGetPhysicalDeviceMemoryProperties vk_get_physical_device_memory_properties;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// extension instance functions
 | 
					// extension instance functions
 | 
				
			||||||
extern PFN_vkCmdBeginDebugUtilsLabelEXT vk_cmd_begin_debug_label;
 | 
					extern PFN_vkCmdBeginDebugUtilsLabelEXT vk_cmd_begin_debug_label;
 | 
				
			||||||
| 
						 | 
					@ -76,29 +75,8 @@ extern PFN_vkCmdBindPipeline vk_cmd_bind_pipeline;
 | 
				
			||||||
extern PFN_vkCmdDraw vk_cmd_draw;
 | 
					extern PFN_vkCmdDraw vk_cmd_draw;
 | 
				
			||||||
extern PFN_vkCmdSetViewport vk_cmd_set_viewport;
 | 
					extern PFN_vkCmdSetViewport vk_cmd_set_viewport;
 | 
				
			||||||
extern PFN_vkCmdSetScissor vk_cmd_set_scissors;
 | 
					extern PFN_vkCmdSetScissor vk_cmd_set_scissors;
 | 
				
			||||||
extern PFN_vkCmdPushConstants vk_cmd_push_constants;
 | 
					 | 
				
			||||||
extern PFN_vkCmdCopyBuffer vk_cmd_copy_buffer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern PFN_vkCreateDescriptorSetLayout vk_create_descriptor_set_layout;
 | 
					 | 
				
			||||||
extern PFN_vkDestroyDescriptorSetLayout vk_destroy_descriptor_set_layout;
 | 
					 | 
				
			||||||
extern PFN_vkCreateDescriptorPool vk_create_descriptor_pool;
 | 
					 | 
				
			||||||
extern PFN_vkDestroyDescriptorPool vk_destroy_descriptor_pool;
 | 
					 | 
				
			||||||
extern PFN_vkAllocateDescriptorSets vk_allocate_descriptor_sets;
 | 
					 | 
				
			||||||
extern PFN_vkFreeDescriptorSets vk_free_descriptor_sets;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
extern PFN_vkCreateBuffer vk_create_buffer;
 | 
					 | 
				
			||||||
extern PFN_vkDestroyBuffer vk_destroy_buffer;
 | 
					 | 
				
			||||||
extern PFN_vkGetBufferMemoryRequirements vk_get_buffer_memory_requirements;
 | 
					 | 
				
			||||||
extern PFN_vkAllocateMemory vk_allocate_memory;
 | 
					 | 
				
			||||||
extern PFN_vkBindBufferMemory vk_bind_buffer_memory;
 | 
					 | 
				
			||||||
extern PFN_vkMapMemory vk_map_memory;
 | 
					 | 
				
			||||||
extern PFN_vkUnmapMemory vk_unmap_memory;
 | 
					 | 
				
			||||||
extern PFN_vkFreeMemory vk_free_memory;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern PFN_vkResetCommandBuffer vk_reset_command_buffer;
 | 
					extern PFN_vkResetCommandBuffer vk_reset_command_buffer;
 | 
				
			||||||
 | 
					 | 
				
			||||||
extern PFN_vkCmdBeginRendering vk_cmd_begin_rendering;
 | 
					 | 
				
			||||||
extern PFN_vkCmdEndRendering vk_cmd_end_rendering;
 | 
					 | 
				
			||||||
// NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables)
 | 
					// NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace lt::renderer::vk
 | 
					} // namespace lt::renderer::vk
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,27 +0,0 @@
 | 
				
			||||||
#include <renderer/backend/vk/data/buffer.hpp>
 | 
					 | 
				
			||||||
#include <renderer/frontend/data/buffer.hpp>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace lt::renderer {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[nodiscard]] /* static */ auto IBuffer::create(
 | 
					 | 
				
			||||||
    Api target_api,
 | 
					 | 
				
			||||||
    class IDevice *device,
 | 
					 | 
				
			||||||
    class IGpu *gpu,
 | 
					 | 
				
			||||||
    const CreateInfo &info
 | 
					 | 
				
			||||||
) -> memory::Scope<IBuffer>
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	ensure(device, "Failed to create renderer::IBuffer: null device");
 | 
					 | 
				
			||||||
	ensure(gpu, "Failed to create renderer::IBuffer: null gpu");
 | 
					 | 
				
			||||||
	ensure(info.size > 0, "Failed to create renderer::IBuffer: null size");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	switch (target_api)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	case Api::vulkan: return memory::create_scope<vk::Buffer>(device, gpu, info);
 | 
					 | 
				
			||||||
	case Api::none:
 | 
					 | 
				
			||||||
	case Api::metal:
 | 
					 | 
				
			||||||
	case Api::direct_x: throw std::runtime_error { "Invalid API" };
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} // namespace lt::renderer
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,66 +0,0 @@
 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <memory/scope.hpp>
 | 
					 | 
				
			||||||
#include <renderer/api.hpp>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace lt::renderer {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class IBuffer
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
	enum class Usage : uint8_t
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		vertex,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		index,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		storage,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		staging,
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct CreateInfo
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		Usage usage;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		size_t size;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		std::string debug_name;
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct CopyInfo
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		size_t offset;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		size_t size;
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	[[nodiscard]] static auto create(
 | 
					 | 
				
			||||||
	    Api target_api,
 | 
					 | 
				
			||||||
	    class IDevice *device,
 | 
					 | 
				
			||||||
	    class IGpu *gpu,
 | 
					 | 
				
			||||||
	    const CreateInfo &info
 | 
					 | 
				
			||||||
	) -> memory::Scope<IBuffer>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	IBuffer() = default;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	virtual ~IBuffer() = default;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	IBuffer(IBuffer &&) = default;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	IBuffer(const IBuffer &) = delete;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	auto operator=(IBuffer &&) -> IBuffer & = default;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	auto operator=(const IBuffer &) -> IBuffer & = delete;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	[[nodiscard]] virtual auto map() -> std::span<std::byte> = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	virtual void unmap() = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	[[nodiscard]] virtual auto get_size() const -> size_t = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
private:
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} // namespace lt::renderer
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,115 +0,0 @@
 | 
				
			||||||
#include <renderer/frontend/data/buffer.hpp>
 | 
					 | 
				
			||||||
#include <renderer/test/utils.hpp>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using ::lt::renderer::IBuffer;
 | 
					 | 
				
			||||||
using enum ::lt::renderer::IMessenger::MessageSeverity;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Suite raii = "buffer_raii"_suite = [] {
 | 
					 | 
				
			||||||
	Case { "happy path won't throw" } = [] {
 | 
					 | 
				
			||||||
		auto fixture = FixtureDeviceSwapchain {};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		for (auto idx = 0; idx <= std::to_underlying(IBuffer::Usage::staging); ++idx)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			ignore = IBuffer::create(
 | 
					 | 
				
			||||||
			    lt::renderer::Api::vulkan,
 | 
					 | 
				
			||||||
			    fixture.device(),
 | 
					 | 
				
			||||||
			    fixture.gpu(),
 | 
					 | 
				
			||||||
			    IBuffer::CreateInfo {
 | 
					 | 
				
			||||||
			        .usage = static_cast<IBuffer::Usage>(idx),
 | 
					 | 
				
			||||||
			        .size = 1000u,
 | 
					 | 
				
			||||||
			        .debug_name = "",
 | 
					 | 
				
			||||||
			    }
 | 
					 | 
				
			||||||
			);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		expect_false(fixture.has_any_messages_of(error));
 | 
					 | 
				
			||||||
		expect_false(fixture.has_any_messages_of(warning));
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Case { "unhappy path throws" } = [] {
 | 
					 | 
				
			||||||
		auto fixture = FixtureDeviceSwapchain {};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		auto info = IBuffer::CreateInfo {
 | 
					 | 
				
			||||||
			.usage = IBuffer::Usage::vertex,
 | 
					 | 
				
			||||||
			.size = 10000u,
 | 
					 | 
				
			||||||
			.debug_name = "",
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		expect_throw([&] {
 | 
					 | 
				
			||||||
			ignore = IBuffer::create(lt::renderer::Api::vulkan, nullptr, fixture.gpu(), info);
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		expect_throw([&] {
 | 
					 | 
				
			||||||
			ignore = IBuffer::create(lt::renderer::Api::vulkan, fixture.device(), nullptr, info);
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		expect_throw([&, info] mutable {
 | 
					 | 
				
			||||||
			info.size = 0;
 | 
					 | 
				
			||||||
			ignore = IBuffer::create(
 | 
					 | 
				
			||||||
			    lt::renderer::Api::vulkan,
 | 
					 | 
				
			||||||
			    fixture.device(),
 | 
					 | 
				
			||||||
			    fixture.gpu(),
 | 
					 | 
				
			||||||
			    info
 | 
					 | 
				
			||||||
			);
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		expect_throw([&] {
 | 
					 | 
				
			||||||
			ignore = IBuffer::create(
 | 
					 | 
				
			||||||
			    lt::renderer::Api::direct_x,
 | 
					 | 
				
			||||||
			    fixture.device(),
 | 
					 | 
				
			||||||
			    fixture.gpu(),
 | 
					 | 
				
			||||||
			    info
 | 
					 | 
				
			||||||
			);
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		expect_throw([&] {
 | 
					 | 
				
			||||||
			ignore = IBuffer::create(
 | 
					 | 
				
			||||||
			    lt::renderer::Api::metal,
 | 
					 | 
				
			||||||
			    fixture.device(),
 | 
					 | 
				
			||||||
			    fixture.gpu(),
 | 
					 | 
				
			||||||
			    info
 | 
					 | 
				
			||||||
			);
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		expect_throw([&] {
 | 
					 | 
				
			||||||
			ignore = IBuffer::create(
 | 
					 | 
				
			||||||
			    lt::renderer::Api::none,
 | 
					 | 
				
			||||||
			    fixture.device(),
 | 
					 | 
				
			||||||
			    fixture.gpu(),
 | 
					 | 
				
			||||||
			    info
 | 
					 | 
				
			||||||
			);
 | 
					 | 
				
			||||||
		});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		/** Make sure the default-case was OK */
 | 
					 | 
				
			||||||
		ignore = IBuffer::create(lt::renderer::Api::vulkan, fixture.device(), fixture.gpu(), info);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		expect_false(fixture.has_any_messages_of(error));
 | 
					 | 
				
			||||||
		expect_false(fixture.has_any_messages_of(warning));
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Suite mapping = "buffer_mapping"_suite = [] {
 | 
					 | 
				
			||||||
	Case { "mapping" } = [] {
 | 
					 | 
				
			||||||
		auto fixture = FixtureDeviceSwapchain {};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		constexpr auto size = 1000u;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		auto buffer = IBuffer::create(
 | 
					 | 
				
			||||||
		    lt::renderer::Api::vulkan,
 | 
					 | 
				
			||||||
		    fixture.device(),
 | 
					 | 
				
			||||||
		    fixture.gpu(),
 | 
					 | 
				
			||||||
		    IBuffer::CreateInfo {
 | 
					 | 
				
			||||||
		        .usage = IBuffer::Usage::staging,
 | 
					 | 
				
			||||||
		        .size = size,
 | 
					 | 
				
			||||||
		        .debug_name = "",
 | 
					 | 
				
			||||||
		    }
 | 
					 | 
				
			||||||
		);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		auto map = buffer->map();
 | 
					 | 
				
			||||||
		expect_eq(map.size(), size);
 | 
					 | 
				
			||||||
		expect_not_nullptr(map.data());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		expect_false(fixture.has_any_messages_of(error));
 | 
					 | 
				
			||||||
		expect_false(fixture.has_any_messages_of(warning));
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
| 
						 | 
					@ -7,7 +7,7 @@ using ::lt::renderer::IMessenger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Suite raii = "pass_raii"_suite = [] {
 | 
					Suite raii = "pass_raii"_suite = [] {
 | 
				
			||||||
	Case { "happy path won't throw" } = [] {
 | 
						Case { "happy path won't throw" } = [] {
 | 
				
			||||||
		Fixture_ auto fixture = Fixture_RendererSystem {};
 | 
							auto fixture = Fixture_RendererSystem {};
 | 
				
			||||||
		auto &system = fixture.renderer_system();
 | 
							auto &system = fixture.renderer_system();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		std::ignore = lt::renderer::IPass::create(
 | 
							std::ignore = lt::renderer::IPass::create(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,10 +1,7 @@
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <math/components/transform.hpp>
 | 
					 | 
				
			||||||
#include <memory/scope.hpp>
 | 
					#include <memory/scope.hpp>
 | 
				
			||||||
#include <renderer/api.hpp>
 | 
					#include <renderer/api.hpp>
 | 
				
			||||||
#include <renderer/components/sprite.hpp>
 | 
					 | 
				
			||||||
#include <renderer/data/frame_constants.hpp>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace lt::renderer {
 | 
					namespace lt::renderer {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,13 +41,6 @@ public:
 | 
				
			||||||
	[[nodiscard]] virtual auto draw(uint32_t frame_idx) -> DrawResult = 0;
 | 
						[[nodiscard]] virtual auto draw(uint32_t frame_idx) -> DrawResult = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	virtual void replace_swapchain(class ISwapchain *swapchain) = 0;
 | 
						virtual void replace_swapchain(class ISwapchain *swapchain) = 0;
 | 
				
			||||||
 | 
					 | 
				
			||||||
	virtual void set_frame_constants(FrameConstants constants) = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	virtual void submit_sprite(
 | 
					 | 
				
			||||||
	    const components::Sprite &sprite,
 | 
					 | 
				
			||||||
	    const math::components::Transform &transform
 | 
					 | 
				
			||||||
	) = 0;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace lt::renderer
 | 
					} // namespace lt::renderer
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,4 @@
 | 
				
			||||||
#include <camera/components.hpp>
 | 
					 | 
				
			||||||
#include <math/algebra.hpp>
 | 
					 | 
				
			||||||
#include <math/components/transform.hpp>
 | 
					 | 
				
			||||||
#include <renderer/components/messenger.hpp>
 | 
					#include <renderer/components/messenger.hpp>
 | 
				
			||||||
#include <renderer/components/sprite.hpp>
 | 
					 | 
				
			||||||
#include <renderer/frontend/context/device.hpp>
 | 
					#include <renderer/frontend/context/device.hpp>
 | 
				
			||||||
#include <renderer/frontend/context/gpu.hpp>
 | 
					#include <renderer/frontend/context/gpu.hpp>
 | 
				
			||||||
#include <renderer/frontend/context/instance.hpp>
 | 
					#include <renderer/frontend/context/instance.hpp>
 | 
				
			||||||
| 
						 | 
					@ -74,30 +70,6 @@ void System::tick(app::TickInfo tick)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto perspective = math::mat4::identity();
 | 
					 | 
				
			||||||
	for (auto [id, camera] : m_registry->view<lt::camera::components::PerspectiveCamera>())
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (camera.is_primary)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			perspective = math::perspective(
 | 
					 | 
				
			||||||
			    camera.vertical_fov,
 | 
					 | 
				
			||||||
			    camera.aspect_ratio,
 | 
					 | 
				
			||||||
			    camera.near_plane,
 | 
					 | 
				
			||||||
			    camera.far_plane
 | 
					 | 
				
			||||||
			);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// for each sprite, submit a new "model matrix"  + "color" to go into the scene's SSBO
 | 
					 | 
				
			||||||
	for (auto &[id, sprite, transform] :
 | 
					 | 
				
			||||||
	     m_registry->view<components::Sprite, math::components::Transform>())
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		m_renderer->submit_sprite(sprite, transform);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	m_renderer->set_frame_constants({ .view_projection = perspective });
 | 
					 | 
				
			||||||
	if (m_renderer->draw(m_frame_idx) != IRenderer::DrawResult::success)
 | 
						if (m_renderer->draw(m_frame_idx) != IRenderer::DrawResult::success)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		m_swapchain.reset();
 | 
							m_swapchain.reset();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -148,6 +148,7 @@ public:
 | 
				
			||||||
		);
 | 
							);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] auto has_any_messages() const -> bool
 | 
						[[nodiscard]] auto has_any_messages() const -> bool
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return m_user_data->m_has_any_messages;
 | 
							return m_user_data->m_has_any_messages;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,77 +0,0 @@
 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <assets/shader.hpp>
 | 
					 | 
				
			||||||
#include <math/vec3.hpp>
 | 
					 | 
				
			||||||
#include <memory/reference.hpp>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace lt::renderer::components {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum class VertexFormat : uint8_t
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	r32_g32_b32_sfloat,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	r32_g32_sfloat,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
enum class VertexInputRate : uint8_t
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	per_vertex,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	per_instance,
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct VertexInputAttributeDescriptipn
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	uint32_t location;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	uint32_t binding;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	uint32_t offset;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	VertexFormat format;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct VertexInputBindingDescription
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	uint32_t binding;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	uint32_t stride;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/** Requires a math::components::Transform component on the same entity to be functional. */
 | 
					 | 
				
			||||||
struct Sprite
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct Vertex
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		math::vec3 position;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		math::vec3 color;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		[[nodiscard]] constexpr static auto get_attributes()
 | 
					 | 
				
			||||||
		    -> std::array<VertexInputAttributeDescriptipn, 2>
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			return {
 | 
					 | 
				
			||||||
				VertexInputAttributeDescriptipn {
 | 
					 | 
				
			||||||
				    .location = 0u,
 | 
					 | 
				
			||||||
				    .binding = 0u,
 | 
					 | 
				
			||||||
				    .offset = offsetof(Sprite::Vertex, position),
 | 
					 | 
				
			||||||
				    .format = VertexFormat::r32_g32_b32_sfloat,
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				VertexInputAttributeDescriptipn {
 | 
					 | 
				
			||||||
				    .location = 1u,
 | 
					 | 
				
			||||||
				    .binding = 0u,
 | 
					 | 
				
			||||||
				    .offset = offsetof(Sprite::Vertex, color),
 | 
					 | 
				
			||||||
				    .format = VertexFormat::r32_g32_b32_sfloat,
 | 
					 | 
				
			||||||
				},
 | 
					 | 
				
			||||||
			};
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	memory::Ref<assets::ShaderAsset> vertex_shader;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	memory::Ref<assets::ShaderAsset> fragment_shader;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} // namespace lt::renderer::components
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,12 +0,0 @@
 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <math/mat4.hpp>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace lt::renderer {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct FrameConstants
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	math::mat4 view_projection;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} // namespace lt::renderer
 | 
					 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace lt::renderer {
 | 
					namespace lt::renderer {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class IMessenger
 | 
					class IMessenger
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -55,6 +55,31 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void tick(app::TickInfo tick) override;
 | 
						void tick(app::TickInfo tick) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						[[nodiscard]] auto get_surface() -> class ISurface *
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return m_surface.get();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						[[nodiscard]] auto get_gpu() -> class IGpu *
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return m_gpu.get();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						[[nodiscard]] auto get_device() -> class IDevice *
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return m_device.get();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						[[nodiscard]] auto get_swapchain() -> class ISwapchain *
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return m_swapchain.get();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						[[nodiscard]] auto get_renderer() -> class IRenderer *
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return m_renderer.get();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] auto get_last_tick_result() const -> const app::TickResult & override
 | 
						[[nodiscard]] auto get_last_tick_result() const -> const app::TickResult & override
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return m_last_tick_result;
 | 
							return m_last_tick_result;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -91,8 +91,8 @@ System::~System()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	catch (const std::exception &exp)
 | 
						catch (const std::exception &exp)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		log::error("Uncaught exception in surface::~System:");
 | 
							log_err("Uncaught exception in surface::~System:");
 | 
				
			||||||
		log::error("\twhat: {}", exp.what());
 | 
							log_err("\twhat: {}", exp.what());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -189,9 +189,9 @@ try
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
catch (const std::exception &exp)
 | 
					catch (const std::exception &exp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	log::error("Exception thrown when on_constructing surface component");
 | 
						log_err("Exception thrown when on_constructing surface component");
 | 
				
			||||||
	log::error("\tentity: {}", entity);
 | 
						log_err("\tentity: {}", entity);
 | 
				
			||||||
	log::error("\twhat: {}", exp.what());
 | 
						log_err("\twhat: {}", exp.what());
 | 
				
			||||||
	m_registry->remove<SurfaceComponent>(entity);
 | 
						m_registry->remove<SurfaceComponent>(entity);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -200,7 +200,7 @@ void System::on_surface_destruct(ecs::Registry ®istry, ecs::EntityId entity)
 | 
				
			||||||
	const auto &[display, window, _] = registry.get<SurfaceComponent>(entity).get_native_data();
 | 
						const auto &[display, window, _] = registry.get<SurfaceComponent>(entity).get_native_data();
 | 
				
			||||||
	if (!display)
 | 
						if (!display)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		log::warn("Surface component destroyed with null display");
 | 
							log_wrn("Surface component destroyed with null display");
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -316,7 +316,7 @@ void System::handle_requests(SurfaceComponent &surface)
 | 
				
			||||||
		[&](const ModifyResolutionRequest &request) { modify_resolution(surface, request); },
 | 
							[&](const ModifyResolutionRequest &request) { modify_resolution(surface, request); },
 | 
				
			||||||
		[&](const ModifyPositionRequest &request) { modify_position(surface, request); },
 | 
							[&](const ModifyPositionRequest &request) { modify_position(surface, request); },
 | 
				
			||||||
		[&](const ModifyVisibilityRequest &request) { modify_visiblity(surface, request); },
 | 
							[&](const ModifyVisibilityRequest &request) { modify_visiblity(surface, request); },
 | 
				
			||||||
		[&](const auto &) { log::error("Unknown surface request"); },
 | 
							[&](const auto &) { log_err("Unknown surface request"); },
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (const auto &request : surface.peek_requests())
 | 
						for (const auto &request : surface.peek_requests())
 | 
				
			||||||
| 
						 | 
					@ -380,7 +380,7 @@ void System::modify_resolution(SurfaceComponent &surface, const ModifyResolution
 | 
				
			||||||
		std::this_thread::sleep_for(std::chrono::microseconds { 100 });
 | 
							std::this_thread::sleep_for(std::chrono::microseconds { 100 });
 | 
				
			||||||
		if (timer.elapsed_time() > lifespan)
 | 
							if (timer.elapsed_time() > lifespan)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			log::error("Timed out waiting for XResizeWindow's event");
 | 
								log_err("Timed out waiting for XResizeWindow's event");
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -419,7 +419,7 @@ void System::modify_position(SurfaceComponent &surface, const ModifyPositionRequ
 | 
				
			||||||
		std::this_thread::sleep_for(std::chrono::microseconds { 100 });
 | 
							std::this_thread::sleep_for(std::chrono::microseconds { 100 });
 | 
				
			||||||
		if (timer.elapsed_time() > lifespan)
 | 
							if (timer.elapsed_time() > lifespan)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			log::error("Timed out waiting for XMoveWindow's event");
 | 
								log_err("Timed out waiting for XMoveWindow's event");
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -268,11 +268,11 @@ Suite tick_handles_requests = "tick_handles_requests"_suite = [] {
 | 
				
			||||||
		expect_eq(surface.get_position(), position);
 | 
							expect_eq(surface.get_position(), position);
 | 
				
			||||||
		expect_eq(surface.get_resolution(), resolution);
 | 
							expect_eq(surface.get_resolution(), resolution);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		log::debug("EVENT COUNT: {}", surface.peek_events().size());
 | 
							log_dbg("EVENT COUNT: {}", surface.peek_events().size());
 | 
				
			||||||
		for (const auto &event : surface.peek_events())
 | 
							for (const auto &event : surface.peek_events())
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			const auto visitor = overloads {
 | 
								const auto visitor = overloads {
 | 
				
			||||||
				[&](auto event) { log::debug("event: {}", event.to_string()); },
 | 
									[&](auto event) { log_dbg("event: {}", event.to_string()); },
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			std::visit(visitor, event);
 | 
								std::visit(visitor, event);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
add_library_module(test test.cpp entrypoint.cpp)
 | 
					add_library_module(test test.cpp entrypoint.cpp)
 | 
				
			||||||
add_library_module(fuzz_test test.cpp fuzz.cpp)
 | 
					add_library_module(fuzz_test test.cpp fuzz.cpp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
target_link_libraries(test PUBLIC logger)
 | 
					target_link_libraries(test PUBLIC tbb logger)
 | 
				
			||||||
target_link_libraries(fuzz_test PUBLIC logger)
 | 
					target_link_libraries(fuzz_test PUBLIC tbb logger)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
add_test_module(test test.test.cpp)
 | 
					add_test_module(test test.test.cpp mock.test.cpp)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -85,14 +85,14 @@ try
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
catch (const std::exception &exp)
 | 
					catch (const std::exception &exp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	lt::log::critical("Terminated due to uncaught exception:");
 | 
						log_crt("Terminated due to uncaught exception:");
 | 
				
			||||||
	lt::log::critical("\twhat: {}", exp.what());
 | 
						log_crt("\twhat: {}", exp.what());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return EXIT_FAILURE;
 | 
						return EXIT_FAILURE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
catch (...)
 | 
					catch (...)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	lt::log::critical("Terminated due to uncaught non-std exception!");
 | 
						log_crt("Terminated due to uncaught non-std exception!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return EXIT_FAILURE;
 | 
						return EXIT_FAILURE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,9 +9,9 @@ try
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
catch (const std::exception &exp)
 | 
					catch (const std::exception &exp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	std::println("Fuzz input resulted in uncaught exception:");
 | 
						std::cout << "Fuzz input resulted in uncaught exception:\n";
 | 
				
			||||||
	std::println("\twhat: {}", exp.what());
 | 
						std::cout << "\texception.what: " << exp.what() << '\n';
 | 
				
			||||||
	std::println("\tinput size: {}", size);
 | 
						std::cout << "\tinput size: " << size << '\n';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return EXIT_FAILURE;
 | 
						return EXIT_FAILURE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										52
									
								
								modules/test/private/mock.test.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								modules/test/private/mock.test.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,52 @@
 | 
				
			||||||
 | 
					#include <test/mock.hpp>
 | 
				
			||||||
 | 
					#include <test/test.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using namespace lt::test;
 | 
				
			||||||
 | 
					using namespace lt::test::mock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ExpensiveClass
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						virtual int expensive(std::string str, std::optional<int> opt)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MockClass: public ExpensiveClass
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						int expensive(std::string str, std::optional<int> opt) override
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return expensive_mock(str, opt);
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Mock<int(std::string, std::optional<int>)> expensive_mock {};
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ExpensiveUser
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						ExpensiveUser(ExpensiveClass &dependency)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							dependency.expensive("", 10);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// problem #1: matcher functions should construct an invokable object to test against the indexed
 | 
				
			||||||
 | 
					// argument.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Suite raii = "mock_raii"_suite = [] {
 | 
				
			||||||
 | 
						Case { "happy path won't throw" } = [] {
 | 
				
			||||||
 | 
							auto a = std::function<int(int)> {};
 | 
				
			||||||
 | 
							auto expensive = MockClass {};
 | 
				
			||||||
 | 
							auto side_effect = false;
 | 
				
			||||||
 | 
							expensive.expensive_mock.expect("test", std::nullopt)
 | 
				
			||||||
 | 
							    .apply([&](auto str, auto opt) { side_effect = true; })
 | 
				
			||||||
 | 
							    .returns(69);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							auto user = ExpensiveUser { expensive };
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										94
									
								
								modules/test/public/mock.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								modules/test/public/mock.hpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,94 @@
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace lt::test {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename _Signature>
 | 
				
			||||||
 | 
					class Mock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<typename Return_Type, typename... Arg_Types>
 | 
				
			||||||
 | 
					class Mock<Return_Type(Arg_Types...)>
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						auto at_least() -> Mock &
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return *this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto operator&&(Mock &mock) -> Mock &
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return mock;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto operator()(Arg_Types... arguments) -> Return_Type
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							++m_call_index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (auto &side_effect : m_side_effects)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								side_effect(std::forward<Arg_Types>(arguments)...);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (m_return_func)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return m_return_func(std::forward<Arg_Types>(arguments)...);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return m_return_value;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/** With any arguments. */
 | 
				
			||||||
 | 
						template<uint32_t counter = 1>
 | 
				
			||||||
 | 
						auto expect() -> Mock &
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							m_expected_counter = counter;
 | 
				
			||||||
 | 
							return *this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto apply(std::function<void(Arg_Types...)> side_effect) -> Mock &
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							m_side_effects.emplace_back(std::move(side_effect));
 | 
				
			||||||
 | 
							return *this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/** Returns a fixed value. */
 | 
				
			||||||
 | 
						auto returns(Return_Type value) -> Mock &
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							m_return_value = value;
 | 
				
			||||||
 | 
							return *this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/** Returns a value based on input. */
 | 
				
			||||||
 | 
						auto returns(std::function<Return_Type(Arg_Types...)> func) -> Mock &
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							m_return_func = std::move(func);
 | 
				
			||||||
 | 
							return *this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						Return_Type m_return_value {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::function<Return_Type(Arg_Types...)> m_return_func {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::vector<std::function<void(Arg_Types...)>> m_side_effects {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t m_call_index = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::vector<std::pair<std::tuple<Arg_Types...>, uint32_t>> m_expected_args;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uint32_t m_expected_counter {};
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace mock::range {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[nodiscard]] auto is_empty() -> bool
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}; // namespace mock::range
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[nodiscard]] auto eq(auto rhs) -> bool
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					} // namespace lt::test
 | 
				
			||||||
| 
						 | 
					@ -178,23 +178,21 @@ private:
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
		case ExecutionPolicy::normal:
 | 
							case ExecutionPolicy::normal:
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			std::println("[-------STATS------]");
 | 
								std::cout << "[-------STATS------]\n"
 | 
				
			||||||
 | 
								          << "suites:\n"
 | 
				
			||||||
 | 
								          << "\ttotal: " << m_total_suite_count << '\n'
 | 
				
			||||||
 | 
								          << "\tpassed: " << m_passed_suite_count << '\n'
 | 
				
			||||||
 | 
								          << "\tfailed: " << m_failed_suite_count << '\n'
 | 
				
			||||||
 | 
								          << "\tmatched: " << m_matched_suite_count << '\n'
 | 
				
			||||||
 | 
								          << "\tskipped: " << m_skipped_suite_count << '\n'
 | 
				
			||||||
 | 
								          << "tests:\n"
 | 
				
			||||||
 | 
								          << "\ttotal: " << m_total_case_count << '\n'
 | 
				
			||||||
 | 
								          << "\tpassed: " << m_passed_case_count << '\n'
 | 
				
			||||||
 | 
								          << "\tfailed: " << m_failed_case_count << '\n'
 | 
				
			||||||
 | 
								          << "\tmatched: " << m_matched_case_count << '\n'
 | 
				
			||||||
 | 
								          << "\tskipped: " << m_skipped_case_count << '\n';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			std::println("suites:");
 | 
								std::cout << "________________________________________________________________\n\n\n";
 | 
				
			||||||
			std::println("\ttotal: {}", m_total_suite_count);
 | 
					 | 
				
			||||||
			std::println("\tpassed: {}", m_passed_suite_count);
 | 
					 | 
				
			||||||
			std::println("\tfailed: {}", m_failed_suite_count);
 | 
					 | 
				
			||||||
			std::println("\tmatched: {}", m_matched_suite_count);
 | 
					 | 
				
			||||||
			std::println("\tskipped: {}", m_skipped_suite_count);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			std::println("tests:");
 | 
					 | 
				
			||||||
			std::println("\ttotal: {}", m_total_case_count);
 | 
					 | 
				
			||||||
			std::println("\tpassed: {}", m_passed_case_count);
 | 
					 | 
				
			||||||
			std::println("\tfailed: {}", m_failed_case_count);
 | 
					 | 
				
			||||||
			std::println("\tmatched: {}", m_matched_case_count);
 | 
					 | 
				
			||||||
			std::println("\tskipped: {}", m_skipped_case_count);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			std::println("________________________________________________________________");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return m_failed_case_count;
 | 
								return m_failed_case_count;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -216,7 +214,7 @@ private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Registry()
 | 
						Registry()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		std::println("________________________________________________________________");
 | 
							std::cout << "________________________________________________________________\n";
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] static auto instance() -> Registry &
 | 
						[[nodiscard]] static auto instance() -> Registry &
 | 
				
			||||||
| 
						 | 
					@ -291,16 +289,16 @@ private:
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		Registry::increment_matched_case_count();
 | 
							Registry::increment_matched_case_count();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		std::println("[Running-----------] --> ");
 | 
							std::cout << "[Running-----------] --> ";
 | 
				
			||||||
		std::println("{}", m_name);
 | 
							std::cout << m_name << '\n';
 | 
				
			||||||
		try
 | 
							try
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			test();
 | 
								test();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		catch (const std::exception &exp)
 | 
							catch (const std::exception &exp)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			std::println("{}", exp.what());
 | 
								std::cout << exp.what() << "\n";
 | 
				
			||||||
			std::println("[-----------FAIL !!]");
 | 
								std::cout << "[-----------FAIL !!]" << "\n\n";
 | 
				
			||||||
			Registry::increment_failed_case_count();
 | 
								Registry::increment_failed_case_count();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (Registry::should_return_on_failure())
 | 
								if (Registry::should_return_on_failure())
 | 
				
			||||||
| 
						 | 
					@ -312,7 +310,7 @@ private:
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Registry::increment_passed_case_count();
 | 
							Registry::increment_passed_case_count();
 | 
				
			||||||
		std::println("[--------SUCCESS :D]");
 | 
							std::cout << "[--------SUCCESS :D]" << "\n\n";
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	std::string_view m_name;
 | 
						std::string_view m_name;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -220,7 +220,7 @@ tar xf 'vulkansdk-linux-x86_64-1.4.328.1.tar.xz' \
 | 
				
			||||||
        -fsanitize-ignorelist=/msan/ignorelist_all_sources \
 | 
					        -fsanitize-ignorelist=/msan/ignorelist_all_sources \
 | 
				
			||||||
        -fno-omit-frame-pointer \
 | 
					        -fno-omit-frame-pointer \
 | 
				
			||||||
        -g \
 | 
					        -g \
 | 
				
			||||||
        -std=c++26 \
 | 
					        -std=c++23 \
 | 
				
			||||||
        -nostdinc++ \
 | 
					        -nostdinc++ \
 | 
				
			||||||
        -isystem /libcxx_msan/include/c++/v1/"\
 | 
					        -isystem /libcxx_msan/include/c++/v1/"\
 | 
				
			||||||
&& export CFLAGS="\
 | 
					&& export CFLAGS="\
 | 
				
			||||||
| 
						 | 
					@ -233,7 +233,7 @@ tar xf 'vulkansdk-linux-x86_64-1.4.328.1.tar.xz' \
 | 
				
			||||||
    -fsanitize-memory-track-origins \
 | 
					    -fsanitize-memory-track-origins \
 | 
				
			||||||
    -fsanitize-ignorelist=/msan/ignorelist_all_sources \
 | 
					    -fsanitize-ignorelist=/msan/ignorelist_all_sources \
 | 
				
			||||||
    -g \
 | 
					    -g \
 | 
				
			||||||
    -std=c++26 \
 | 
					    -std=c++23 \
 | 
				
			||||||
    -L/msan/lib -Wl,-rpath,/msan/lib \
 | 
					    -L/msan/lib -Wl,-rpath,/msan/lib \
 | 
				
			||||||
    -L/libcxx_msan/lib -Wl,-rpath,/libcxx_msan/lib \
 | 
					    -L/libcxx_msan/lib -Wl,-rpath,/libcxx_msan/lib \
 | 
				
			||||||
    -lc++ \
 | 
					    -lc++ \
 | 
				
			||||||
| 
						 | 
					@ -272,7 +272,7 @@ export CXXFLAGS="\
 | 
				
			||||||
        -fsanitize-ignorelist=/msan/ignorelist_all_sources \
 | 
					        -fsanitize-ignorelist=/msan/ignorelist_all_sources \
 | 
				
			||||||
        -fno-omit-frame-pointer \
 | 
					        -fno-omit-frame-pointer \
 | 
				
			||||||
        -g \
 | 
					        -g \
 | 
				
			||||||
        -std=c++26 \
 | 
					        -std=c++23 \
 | 
				
			||||||
        -nostdinc++ \
 | 
					        -nostdinc++ \
 | 
				
			||||||
        -isystem /libcxx_msan/include/c++/v1/"\
 | 
					        -isystem /libcxx_msan/include/c++/v1/"\
 | 
				
			||||||
&& export CFLAGS="\
 | 
					&& export CFLAGS="\
 | 
				
			||||||
| 
						 | 
					@ -285,7 +285,7 @@ export CXXFLAGS="\
 | 
				
			||||||
    -fsanitize-memory-track-origins \
 | 
					    -fsanitize-memory-track-origins \
 | 
				
			||||||
    -fsanitize-ignorelist=/msan/ignorelist_all_sources \
 | 
					    -fsanitize-ignorelist=/msan/ignorelist_all_sources \
 | 
				
			||||||
    -g \
 | 
					    -g \
 | 
				
			||||||
    -std=c++26 \
 | 
					    -std=c++23 \
 | 
				
			||||||
    -L/msan/lib -Wl,-rpath,/msan/lib \
 | 
					    -L/msan/lib -Wl,-rpath,/msan/lib \
 | 
				
			||||||
    -L/libcxx_msan/lib -Wl,-rpath,/libcxx_msan/lib \
 | 
					    -L/libcxx_msan/lib -Wl,-rpath,/libcxx_msan/lib \
 | 
				
			||||||
    -lc++ \
 | 
					    -lc++ \
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,14 +34,14 @@ cmake \
 | 
				
			||||||
-fsanitize-memory-track-origins \
 | 
					-fsanitize-memory-track-origins \
 | 
				
			||||||
-g \
 | 
					-g \
 | 
				
			||||||
-fno-omit-frame-pointer \
 | 
					-fno-omit-frame-pointer \
 | 
				
			||||||
-std=c++26 \
 | 
					-std=c++23 \
 | 
				
			||||||
-nostdinc++ \
 | 
					-nostdinc++ \
 | 
				
			||||||
-isystem /libcxx_msan/include/c++/v1/" \
 | 
					-isystem /libcxx_msan/include/c++/v1/" \
 | 
				
			||||||
    -D CMAKE_EXE_LINKER_FLAGS=" \
 | 
					    -D CMAKE_EXE_LINKER_FLAGS=" \
 | 
				
			||||||
-fsanitize=memory \
 | 
					-fsanitize=memory \
 | 
				
			||||||
-fsanitize-memory-track-origins \
 | 
					-fsanitize-memory-track-origins \
 | 
				
			||||||
-g \
 | 
					-g \
 | 
				
			||||||
-std=c++26 \
 | 
					-std=c++23 \
 | 
				
			||||||
-L/msan/lib -Wl,-rpath,/msan/lib \
 | 
					-L/msan/lib -Wl,-rpath,/msan/lib \
 | 
				
			||||||
-L/libcxx_msan/lib -Wl,-rpath,/libcxx_msan/lib \
 | 
					-L/libcxx_msan/lib -Wl,-rpath,/libcxx_msan/lib \
 | 
				
			||||||
-lc++ \
 | 
					-lc++ \
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,7 +22,7 @@ cmake \
 | 
				
			||||||
    -D CMAKE_LINKER_TYPE=MOLD \
 | 
					    -D CMAKE_LINKER_TYPE=MOLD \
 | 
				
			||||||
    -D ENABLE_UNIT_TESTS=ON \
 | 
					    -D ENABLE_UNIT_TESTS=ON \
 | 
				
			||||||
    -D CMAKE_BUILD_TYPE=Release \
 | 
					    -D CMAKE_BUILD_TYPE=Release \
 | 
				
			||||||
    -D CMAKE_CXX_FLAGS="-std=c++26 -g -fno-omit-frame-pointer"
 | 
					    -D CMAKE_CXX_FLAGS="-std=c++23 -g -fno-omit-frame-pointer"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cmake --build ./build -j"$(nproc)"
 | 
					cmake --build ./build -j"$(nproc)"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,7 +25,7 @@ cmake \
 | 
				
			||||||
    -D CMAKE_LINKER_TYPE=MOLD \
 | 
					    -D CMAKE_LINKER_TYPE=MOLD \
 | 
				
			||||||
    -D ENABLE_UNIT_TESTS=ON \
 | 
					    -D ENABLE_UNIT_TESTS=ON \
 | 
				
			||||||
    -D CMAKE_BUILD_TYPE=Release \
 | 
					    -D CMAKE_BUILD_TYPE=Release \
 | 
				
			||||||
    -D CMAKE_CXX_FLAGS="-std=c++26 -fno-omit-frame-pointer -fno-common -g"
 | 
					    -D CMAKE_CXX_FLAGS="-std=c++23 -fno-omit-frame-pointer -fno-common -g"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cmake --build ./build -j"$(nproc)"
 | 
					cmake --build ./build -j"$(nproc)"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,7 +20,8 @@ RUN apk add --no-cache \
 | 
				
			||||||
    openssh
 | 
					    openssh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN pip install --no-cache-dir --break-system-packages \
 | 
					RUN pip install --no-cache-dir --break-system-packages \
 | 
				
			||||||
 | 
					    conan \
 | 
				
			||||||
 | 
					    gitpython \
 | 
				
			||||||
    Sphinx \
 | 
					    Sphinx \
 | 
				
			||||||
    sphinx_rtd_theme \
 | 
					    sphinx_rtd_theme \
 | 
				
			||||||
    gitpython \
 | 
					    && conan profile detect
 | 
				
			||||||
    breathe
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,6 +17,6 @@ cmake \
 | 
				
			||||||
    -D ENABLE_UNIT_TESTS=ON \
 | 
					    -D ENABLE_UNIT_TESTS=ON \
 | 
				
			||||||
    -D ENABLE_STATIC_ANALYSIS=ON \
 | 
					    -D ENABLE_STATIC_ANALYSIS=ON \
 | 
				
			||||||
    -D CMAKE_BUILD_TYPE=Release \
 | 
					    -D CMAKE_BUILD_TYPE=Release \
 | 
				
			||||||
    -D CMAKE_CXX_FLAGS="-std=c++26 -stdlib=libc++"
 | 
					    -D CMAKE_CXX_FLAGS="-std=c++23 -stdlib=libc++"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cmake --build . -j"$(nproc)"
 | 
					cmake --build . -j"$(nproc)"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue