Skip to content

Commit

Permalink
Merge pull request #70 from japsuu/dev
Browse files Browse the repository at this point in the history
Add builtin profiling support
  • Loading branch information
japsuu authored Oct 30, 2024
2 parents b56df1d + e1abdba commit 08374e5
Show file tree
Hide file tree
Showing 59 changed files with 941 additions and 262 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ Desktop.ini

# Build folder
[Bb]uilds/
[Bb]uild/

# DocFx
.cache
**/_site/

# User tools folder (profiler, etc)
[Tt]ools/[Uu]ser/
36 changes: 36 additions & 0 deletions docs/manual/build-configurations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@

# Build Configurations

The KorpiEngine solution has three default build configurations: `Debug`, `Release`, and `Production`.

Each build configuration has a different use case and is optimized for different scenarios.

## Default Build Configurations

The `Debug` build configuration is used for development and debugging purposes.
It is the slowest build configuration with all optimizations disabled,
but it has the most debugging information available.

The `Release` build configuration is used for testing and performance profiling.
It is faster than the `Debug` build configuration with some optimizations enabled,
but still has most of the debugging information available.

The `Production` build configuration is used for shipping the final product.
It is the fastest build configuration with all optimizations enabled,
and all tooling and debugging information stripped.

<br/>

## Default Preprocessor Defines

The following preprocessor defines are available in KorpiEngine projects,
in addition to the default ones (e.g. `NETCOREAPP`, `NET`, etc.) provided by the .NET SDK.

| Preprocessor define | Debug | Release | Production | Description |
|---------------------|:-----:|:-------:|:----------:|-----------------------------------------------------|
| `KORPI_DEBUG` || | | This is the debug build configuration. |
| `KORPI_RELEASE` | || | This is the release build configuration. |
| `KORPI_PRODUCTION` | | || This is the production build configuration. |
| `KORPI_PROFILE` ||| | Profiling functionality is included with the build. |
| `KORPI_TOOLS` ||| | Tooling functionality is included with the build. |
| `KORPI_OPTIMIZED` | ||| Optimized code compilation is enabled. |
2 changes: 1 addition & 1 deletion docs/manual/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ The example has multiple scenes, each showcasing different features of the engin
- With the **TERMINAL**:
- `cd ./KorpiEngine/src/Sandbox`
- `dotnet build ./Sandbox.csproj`
- The built executable is now located at `./bin/<configuration>/<framework>/Sandbox.exe`
- The built executable is now located at `KorpiEngine/Build/<configuration>/<framework>/Sandbox.exe`

<br/>

Expand Down
10 changes: 6 additions & 4 deletions docs/manual/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@ Korpi Engine **DOES** aim to
- offer a clean and simple API
- adhere to the [KISS principle](https://en.m.wikipedia.org/wiki/KISS_principle)
- be a good learning tool for game/engine development
- be modular and extensible, to allow for easy integration of new features and systems.
- be modular and extensible, allowing for easy integration of new features and systems.

<br/>

## Which types of games is Korpi Engine best suited for?

- **Open-world games**: The engine is designed to handle large worlds with minimal additional programmer effort.
- **Procedural generation**: The APIs have been designed to support custom procedurally generated meshes.
- **Games with highly specialized requirements**: The engine can be used as a rendering engine, allowing for custom systems.
- **Systematic games**: Programmers have full control over their game systems.
- **Open-world games**: The engine handles large worlds with minimal additional programmer effort.
- **Procedural generation**: The APIs have been designed to support custom procedurally generated content.

An example of such a game could be a Minecraft-like voxel game, or a deep-space exploration game.

Expand All @@ -40,4 +42,4 @@ An example of such a game could be a Minecraft-like voxel game, or a deep-space

## Why the name "Korpi"?

The name "Korpi" is Finnish and means "wilderness" or "forest". It was chosen to reflect the engine's focus on large, open-world games.
The name "Korpi" is Finnish and means "wilderness" or "forest". It was chosen to reflect the engine's focus on large-scale games.
102 changes: 102 additions & 0 deletions docs/manual/profiling.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@

# Profiling

KorpiEngine uses the `Tracy` profiler to measure the performance of the engine.
_Tracy is a real-time, nanosecond resolution, remote telemetry, hybrid frame and sampling profiler for games and other applications_.

Profiling functionality incurs a small performance overhead.
For this reason all profiling functionality is stripped from the build if the `KORPI_PROFILE` preprocessor directive is not defined.
Read more about [build configurations and preprocessor defines](build-configurations.md).

> [!NOTE]
> `KORPI_PROFILE` is defined by default for `Debug` and `Release` builds, but **NOT** for `Production` builds.
<br/>

## Usage

1. Download the latest Tracy profiler from [here](https://github.com/wolfpld/tracy/releases) and extract the downloaded archive.
2. Run the `tracy-profiler` executable, located in the extracted archive.
3. Run your game/application with a build configuration that has profiling enabled (see above).
4. The profiler should discover the running game/application instance. _Double-click_ on the instance to connect to it.

<br/>

## Custom Profiling

To profile a specific part of your code,
you can either use the <xref:KorpiEngine.Tools.ProfileAttribute> or the <xref:KorpiEngine.Tools.IProfilerZone> interface.

<br/>

### By attribute

When using a <xref:KorpiEngine.Tools.ProfileAttribute> the profiling code
is injected around the method at build-time, using `AspectInjector`).
This approach is useful when you want to quickly profile a method without modifying the code,
but it's not as flexible.

> [!NOTE]
> The profiling code is only injected when `KORPI_PROFILE` is defined.
```csharp

[Profile]
public void MyMethod()
{
// Code to profile
// ...
}
```

<br/>

### By zone

The <xref:KorpiEngine.Tools.Profiler> provided by `Application.Profiler` provides a more flexible interface
to start and stop profiling a specific block of code, and plotting data in the profiler.
This approach is way more verbose than using the `Profile` attribute, but it's also more flexible.

> [!IMPORTANT]
> Make sure to dispose of the `IProfilerZone`.
```csharp
IProfilerZone zone = Application.Profiler.BeginZone("MyZone");

// Code to profile
// ...
if (condition)
zone.EmitText("Something happened!");
// ...
zone.Dispose();
```

You can also use a `using` statement to automatically dispose the zone.

```csharp
using (IProfilerZone zone = Application.Profiler.BeginZone("MyZone"))
{
// Code to profile
// ...
}
```

<br/>

## GPU Profiling

GPU profiling is not yet supported.

<br/>

## Advanced

You can also use the `Tracy` API directly to profile your code.
This bypasses the `KorpiEngine` profiling system.

We use [clibequilibrium/Tracy-CSharp](https://github.com/clibequilibrium/Tracy-CSharp) bindings
to interact with the `Tracy` profiler.

> [!TIP]
> Use Tracy's [PDF manual](https://github.com/wolfpld/tracy/releases) to learn more about the Tracy API.
2 changes: 1 addition & 1 deletion docs/manual/shaders.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ The KSL files are compiled into GLSL, so you can use any GLSL code/syntax in you

## Shader Files

Shader files are text files with the `.ksl` extension. They can be [loaded at runtime](external-assets.md) using the `AssetManager` API.
Shader files are text files with the `.ksl` extension. They can be [loaded at runtime](assets.md) using the `Application.AssetProvider` API.

<br/>

Expand Down
4 changes: 4 additions & 0 deletions docs/manual/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@
href: introduction.md
- name: Getting Started
href: getting-started.md
- name: Build Configurations
href: build-configurations.md
- name: Scripting
href: scripting.md
- name: Profiling
href: profiling.md
- name: Coordinate Systems
href: coordinate-systems.md
- name: Math
Expand Down
18 changes: 18 additions & 0 deletions src/Core.Tests/Core.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,24 @@
<RootNamespace>KorpiEngine.Core.Tests</RootNamespace>
</PropertyGroup>

<!-- Debug configuration -->
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DefineConstants>KORPI_DEBUG;KORPI_TOOLS;KORPI_PROFILE;TRACY_ENABLE;TRACE</DefineConstants>
<OutputPath>..\..\Build\Debug\</OutputPath>
</PropertyGroup>

<!-- Release configuration -->
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DefineConstants>KORPI_RELEASE;KORPI_TOOLS;KORPI_PROFILE;KORPI_OPTIMIZE;TRACY_ENABLE;TRACE</DefineConstants>
<OutputPath>..\..\Build\Release\</OutputPath>
</PropertyGroup>

<!-- Production configuration -->
<PropertyGroup Condition=" '$(Configuration)' == 'Production' ">
<DefineConstants>KORPI_PRODUCTION;KORPI_OPTIMIZE</DefineConstants>
<OutputPath>..\..\Build\Production\</OutputPath>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0"/>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0"/>
Expand Down
Loading

0 comments on commit 08374e5

Please sign in to comment.