Skip to content

Commit

Permalink
AtlasEngine: Make shader hot-reloads possible in Windows Terminal (#1…
Browse files Browse the repository at this point in the history
…2227)

This minor change makes it possible to hot-reload the AtlasEngine shaders under
Windows Terminal. Launching an UWP application from Visual Studio doesn't
necessarily result in a working directory inside the project folder,
which makes relative file paths impractical. While the `__FILE__` macro is
compiler dependent it works under our build setup with MSVC at least.

## Validation Steps Performed

* Shader hot-reloading works under Windows Terminal ✅
  • Loading branch information
lhecker authored Jan 24, 2022
1 parent e3aa9ff commit 27c4a84
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 17 deletions.
31 changes: 15 additions & 16 deletions src/renderer/atlas/AtlasEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@

#include "../../interactivity/win32/CustomWindowMessages.h"

#define SHADER_SOURCE_DIRECTORY LR"(..\..\renderer\atlas\)"

// #### NOTE ####
// This file should only contain methods that are only accessed by the caller of Present() (the "Renderer" class).
// Basically this file poses the "synchronization" point between the concurrently running
Expand Down Expand Up @@ -192,16 +190,17 @@ AtlasEngine::AtlasEngine()
_sr.isWindows10OrGreater = IsWindows10OrGreater();

#ifndef NDEBUG
// If you run the Host.EXE project inside Visual Studio it'll have a working directory of
// $(SolutionDir)\src\host\exe. This relative path will thus end up in this source directory.
_sr.sourceCodeWatcher = wil::make_folder_change_reader_nothrow(SHADER_SOURCE_DIRECTORY, false, wil::FolderChangeEvents::FileName | wil::FolderChangeEvents::LastWriteTime, [this](wil::FolderChangeEvent, PCWSTR path) {
if (til::ends_with(path, L".hlsl"))
{
auto expected = INT64_MAX;
const auto invalidationTime = std::chrono::steady_clock::now() + std::chrono::milliseconds(100);
_sr.sourceCodeInvalidationTime.compare_exchange_strong(expected, invalidationTime.time_since_epoch().count(), std::memory_order_relaxed);
}
});
{
_sr.sourceDirectory = std::filesystem::path{ __FILE__ }.parent_path();
_sr.sourceCodeWatcher = wil::make_folder_change_reader_nothrow(_sr.sourceDirectory.c_str(), false, wil::FolderChangeEvents::FileName | wil::FolderChangeEvents::LastWriteTime, [this](wil::FolderChangeEvent, PCWSTR path) {
if (til::ends_with(path, L".hlsl"))
{
auto expected = INT64_MAX;
const auto invalidationTime = std::chrono::steady_clock::now() + std::chrono::milliseconds(100);
_sr.sourceCodeInvalidationTime.compare_exchange_strong(expected, invalidationTime.time_since_epoch().count(), std::memory_order_relaxed);
}
});
}
#endif
}

Expand Down Expand Up @@ -265,8 +264,8 @@ try

try
{
static const auto compile = [](const wchar_t* path, const char* target) {
const wil::unique_hfile fileHandle{ CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr) };
static const auto compile = [](const std::filesystem::path& path, const char* target) {
const wil::unique_hfile fileHandle{ CreateFileW(path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr) };
THROW_LAST_ERROR_IF(!fileHandle);

const auto fileSize = GetFileSize(fileHandle.get(), nullptr);
Expand Down Expand Up @@ -303,8 +302,8 @@ try
return blob;
};

const auto vs = compile(SHADER_SOURCE_DIRECTORY "shader_vs.hlsl", "vs_4_1");
const auto ps = compile(SHADER_SOURCE_DIRECTORY "shader_ps.hlsl", "ps_4_1");
const auto vs = compile(_sr.sourceDirectory / L"shader_vs.hlsl", "vs_4_1");
const auto ps = compile(_sr.sourceDirectory / L"shader_ps.hlsl", "ps_4_1");

THROW_IF_FAILED(_r.device->CreateVertexShader(vs->GetBufferPointer(), vs->GetBufferSize(), nullptr, _r.vertexShader.put()));
THROW_IF_FAILED(_r.device->CreatePixelShader(ps->GetBufferPointer(), ps->GetBufferSize(), nullptr, _r.pixelShader.put()));
Expand Down
1 change: 1 addition & 0 deletions src/renderer/atlas/AtlasEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,7 @@ namespace Microsoft::Console::Render
bool isWindows10OrGreater = true;

#ifndef NDEBUG
std::filesystem::path sourceDirectory;
wil::unique_folder_change_reader_nothrow sourceCodeWatcher;
std::atomic<int64_t> sourceCodeInvalidationTime{ INT64_MAX };
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/atlas/pch.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#define WIN32_LEAN_AND_MEAN

#include <array>
#include <iomanip>
#include <filesystem>
#include <optional>
#include <sstream>
#include <string_view>
Expand Down

0 comments on commit 27c4a84

Please sign in to comment.