Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added experimental.pixelShaderImagePath #14073

Merged
merged 13 commits into from
Mar 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions samples/PixelShaders/BackgroundImage.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Demo shader to show passing in an image using
// experimental.pixelShaderImagePath. This shader simply displays the Terminal
// contents on top of the given image.
//
// The image loaded by the terminal will be placed into the `image` texture.

SamplerState samplerState;
Texture2D shaderTexture : register(t0);
Texture2D image : register(t1);

cbuffer PixelShaderSettings {
float Time;
float Scale;
float2 Resolution;
float4 Background;
};

float4 main(float4 pos : SV_POSITION, float2 tex : TEXCOORD) : SV_TARGET
{
float4 terminalColor = shaderTexture.Sample(samplerState, tex);
float4 imageColor = image.Sample(samplerState, tex);
return lerp(imageColor, terminalColor, terminalColor.a);
}
2 changes: 2 additions & 0 deletions src/cascadia/TerminalControl/ControlCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation

_renderEngine->SetRetroTerminalEffect(_settings->RetroTerminalEffect());
_renderEngine->SetPixelShaderPath(_settings->PixelShaderPath());
_renderEngine->SetPixelShaderImagePath(_settings->PixelShaderImagePath());
_renderEngine->SetForceFullRepaintRendering(_settings->ForceFullRepaintRendering());
_renderEngine->SetSoftwareRendering(_settings->SoftwareRendering());

Expand Down Expand Up @@ -914,6 +915,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_renderEngine->SetSelectionBackground(til::color{ newAppearance->SelectionBackground() });
_renderEngine->SetRetroTerminalEffect(newAppearance->RetroTerminalEffect());
_renderEngine->SetPixelShaderPath(newAppearance->PixelShaderPath());
_renderEngine->SetPixelShaderImagePath(newAppearance->PixelShaderImagePath());

// Incase EnableUnfocusedAcrylic is disabled and Focused Acrylic is set to true,
// the terminal should ignore the unfocused opacity from settings.
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalControl/IControlAppearance.idl
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ namespace Microsoft.Terminal.Control
// Experimental settings
Boolean RetroTerminalEffect { get; };
String PixelShaderPath { get; };
String PixelShaderImagePath { get; };
};
}
2 changes: 1 addition & 1 deletion src/cascadia/TerminalCore/Terminal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1602,7 +1602,7 @@ til::point Terminal::GetViewportRelativeCursorPosition() const noexcept
// These functions are used by TerminalInput, which must build in conhost
// against OneCore compatible signatures. See the definitions in
// VtApiRedirection.hpp (which we cannot include cross-project.)
// Since we do nto run on OneCore, we can dispense with the compatibility
mrange marked this conversation as resolved.
Show resolved Hide resolved
// Since we don't run on OneCore, we can dispense with the compatibility
// shims.
extern "C" UINT OneCoreSafeMapVirtualKeyW(_In_ UINT uCode, _In_ UINT uMapType)
{
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalSettingsModel/IAppearanceConfig.idl
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ namespace Microsoft.Terminal.Settings.Model

INHERITABLE_APPEARANCE_SETTING(Boolean, RetroTerminalEffect);
INHERITABLE_APPEARANCE_SETTING(String, PixelShaderPath);
INHERITABLE_APPEARANCE_SETTING(String, PixelShaderImagePath);
INHERITABLE_APPEARANCE_SETTING(IntenseStyle, IntenseTextStyle);
INHERITABLE_APPEARANCE_SETTING(Microsoft.Terminal.Core.AdjustTextMode, AdjustIndistinguishableColors);
INHERITABLE_APPEARANCE_SETTING(Double, Opacity);
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalSettingsModel/MTSMSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ Author(s):
X(winrt::Windows::UI::Xaml::Media::Stretch, BackgroundImageStretchMode, "backgroundImageStretchMode", winrt::Windows::UI::Xaml::Media::Stretch::UniformToFill) \
X(bool, RetroTerminalEffect, "experimental.retroTerminalEffect", false) \
X(hstring, PixelShaderPath, "experimental.pixelShaderPath") \
X(hstring, PixelShaderImagePath, "experimental.pixelShaderImagePath") \
X(ConvergedAlignment, BackgroundImageAlignment, "backgroundImageAlignment", ConvergedAlignment::Horizontal_Center | ConvergedAlignment::Vertical_Center) \
X(hstring, BackgroundImagePath, "backgroundImage") \
X(Model::IntenseStyle, IntenseTextStyle, "intenseTextStyle", Model::IntenseStyle::Bright) \
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalSettingsModel/TerminalSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation

_RetroTerminalEffect = appearance.RetroTerminalEffect();
_PixelShaderPath = winrt::hstring{ wil::ExpandEnvironmentStringsW<std::wstring>(appearance.PixelShaderPath().c_str()) };
_PixelShaderImagePath = winrt::hstring{ wil::ExpandEnvironmentStringsW<std::wstring>(appearance.PixelShaderImagePath().c_str()) };

_IntenseIsBold = WI_IsFlagSet(appearance.IntenseTextStyle(), Microsoft::Terminal::Settings::Model::IntenseStyle::Bold);
_IntenseIsBright = WI_IsFlagSet(appearance.IntenseTextStyle(), Microsoft::Terminal::Settings::Model::IntenseStyle::Bright);
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalSettingsModel/TerminalSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
INHERITABLE_SETTING(Model::TerminalSettings, bool, ForceVTInput, false);

INHERITABLE_SETTING(Model::TerminalSettings, hstring, PixelShaderPath);
INHERITABLE_SETTING(Model::TerminalSettings, hstring, PixelShaderImagePath);

INHERITABLE_SETTING(Model::TerminalSettings, bool, Elevate, false);

Expand Down
3 changes: 2 additions & 1 deletion src/cascadia/inc/ControlProperties.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
X(winrt::Windows::UI::Xaml::HorizontalAlignment, BackgroundImageHorizontalAlignment, winrt::Windows::UI::Xaml::HorizontalAlignment::Center) \
X(winrt::Windows::UI::Xaml::VerticalAlignment, BackgroundImageVerticalAlignment, winrt::Windows::UI::Xaml::VerticalAlignment::Center) \
X(bool, RetroTerminalEffect, false) \
X(winrt::hstring, PixelShaderPath)
X(winrt::hstring, PixelShaderPath) \
X(winrt::hstring, PixelShaderImagePath)

// --------------------------- Core Settings ---------------------------
// All of these settings are defined in ICoreSettings.
Expand Down
16 changes: 16 additions & 0 deletions src/renderer/atlas/AtlasEngine.api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,11 @@ HRESULT AtlasEngine::Enable() noexcept
return _api.s->misc->customPixelShaderPath;
}

[[nodiscard]] std::wstring_view AtlasEngine::GetPixelShaderImagePath() noexcept
{
return _api.s->misc->customPixelShaderImagePath;
}

[[nodiscard]] bool AtlasEngine::GetRetroTerminalEffect() const noexcept
{
return _api.s->misc->useRetroTerminalEffect;
Expand Down Expand Up @@ -400,6 +405,17 @@ try
}
CATCH_LOG()

void AtlasEngine::SetPixelShaderImagePath(std::wstring_view value) noexcept
try
{
if (_api.s->misc->customPixelShaderImagePath != value)
{
_api.s.write()->misc.write()->customPixelShaderImagePath = value;
_resolveTransparencySettings();
}
}
CATCH_LOG()

void AtlasEngine::SetRetroTerminalEffect(bool enable) noexcept
{
if (_api.s->misc->useRetroTerminalEffect != enable)
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/atlas/AtlasEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -643,7 +643,7 @@ void AtlasEngine::_recreateCellCountDependentResources()
// and 40x (AMD) faster for allocations with an alignment of 32 or greater.
// backgroundBitmapStride is a "count" of u32 and not in bytes,
// so we round up to multiple of 8 because 8 * sizeof(u32) == 32.
_p.colorBitmapRowStride = (static_cast<size_t>(_p.s->viewportCellCount.x) + 7) & ~7;
_p.colorBitmapRowStride = alignForward<size_t>(_p.s->viewportCellCount.x, 8);
_p.colorBitmapDepthStride = _p.colorBitmapRowStride * _p.s->viewportCellCount.y;
_p.colorBitmap = Buffer<u32, 32>(_p.colorBitmapDepthStride * 2);
_p.backgroundBitmap = { _p.colorBitmap.data(), _p.colorBitmapDepthStride };
Expand Down
2 changes: 2 additions & 0 deletions src/renderer/atlas/AtlasEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ namespace Microsoft::Console::Render::Atlas
// DxRenderer - getter
HRESULT Enable() noexcept override;
[[nodiscard]] std::wstring_view GetPixelShaderPath() noexcept override;
[[nodiscard]] std::wstring_view GetPixelShaderImagePath() noexcept override;
[[nodiscard]] bool GetRetroTerminalEffect() const noexcept override;
[[nodiscard]] float GetScaling() const noexcept override;
[[nodiscard]] Types::Viewport GetViewportInCharacters(const Types::Viewport& viewInPixels) const noexcept override;
Expand All @@ -72,6 +73,7 @@ namespace Microsoft::Console::Render::Atlas
void SetForceFullRepaintRendering(bool enable) noexcept override;
[[nodiscard]] HRESULT SetHwnd(HWND hwnd) noexcept override;
void SetPixelShaderPath(std::wstring_view value) noexcept override;
void SetPixelShaderImagePath(std::wstring_view value) noexcept override;
void SetRetroTerminalEffect(bool enable) noexcept override;
void SetSelectionBackground(COLORREF color, float alpha = 0.5f) noexcept override;
void SetSoftwareRendering(bool enable) noexcept override;
Expand Down
7 changes: 7 additions & 0 deletions src/renderer/atlas/Backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,13 @@ namespace Microsoft::Console::Render::Atlas
return val < min ? min : (max < val ? max : val);
}

template<typename T>
constexpr T alignForward(T val, T alignment) noexcept
{
assert((alignment & (alignment - 1)) == 0); // alignment should be a power of 2
return (val + alignment - 1) & ~(alignment - 1);
}

inline constexpr D2D1_RECT_F GlyphRunEmptyBounds{ 1e38f, 1e38f, -1e38f, -1e38f };
void GlyphRunAccumulateBounds(const ID2D1DeviceContext* d2dRenderTarget, D2D1_POINT_2F baselineOrigin, const DWRITE_GLYPH_RUN* glyphRun, D2D1_RECT_F& bounds);

Expand Down
32 changes: 26 additions & 6 deletions src/renderer/atlas/BackendD3D.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,13 @@

#include "BuiltinGlyphs.h"
#include "dwrite.h"
#include "wic.h"
#include "../../types/inc/ColorFix.hpp"

#if ATLAS_DEBUG_SHOW_DIRTY || ATLAS_DEBUG_COLORIZE_GLYPH_ATLAS
#include "colorbrewer.h"
#endif

#if ATLAS_DEBUG_DUMP_RENDER_TARGET
#include "wic.h"
#endif

TIL_FAST_MATH_BEGIN

#pragma warning(disable : 4100) // '...': unreferenced formal parameter
Expand Down Expand Up @@ -345,6 +342,8 @@ void BackendD3D::_recreateCustomShader(const RenderingPayload& p)
_customPixelShader.reset();
_customShaderConstantBuffer.reset();
_customShaderSamplerState.reset();
_customShaderTexture.reset();
_customShaderTextureView.reset();
_requiresContinuousRedraw = false;

if (!p.s->misc->customPixelShaderPath.empty())
Expand Down Expand Up @@ -436,6 +435,23 @@ void BackendD3D::_recreateCustomShader(const RenderingPayload& p)
p.warningCallback(D2DERR_SHADER_COMPILE_FAILED);
}
}

if (!p.s->misc->customPixelShaderImagePath.empty())
{
try
{
WIC::LoadTextureFromFile(p.device.get(), p.s->misc->customPixelShaderImagePath.c_str(), _customShaderTexture.addressof(), _customShaderTextureView.addressof());
}
catch (...)
{
LOG_CAUGHT_EXCEPTION();
_customPixelShader.reset();
if (p.warningCallback)
{
p.warningCallback(D2DERR_SHADER_COMPILE_FAILED);
}
}
}
}
else if (p.s->misc->useRetroTerminalEffect)
{
Expand Down Expand Up @@ -899,7 +915,7 @@ void BackendD3D::_recreateInstanceBuffers(const RenderingPayload& p)
auto newSize = newCapacity * sizeof(QuadInstance);
// Round up to multiples of 64kB to avoid reallocating too often.
// 64kB is the minimum alignment for committed resources in D3D12.
newSize = (newSize + 0xffff) & ~size_t{ 0xffff };
newSize = alignForward<size_t>(newSize, 64 * 1024);
newCapacity = newSize / sizeof(QuadInstance);

_instanceBuffer.reset();
Expand Down Expand Up @@ -2121,7 +2137,11 @@ void BackendD3D::_executeCustomShader(RenderingPayload& p)
// PS: Pixel Shader
p.deviceContext->PSSetShader(_customPixelShader.get(), nullptr, 0);
p.deviceContext->PSSetConstantBuffers(0, 1, _customShaderConstantBuffer.addressof());
p.deviceContext->PSSetShaderResources(0, 1, _customOffscreenTextureView.addressof());
ID3D11ShaderResourceView* const resourceViews[]{
_customOffscreenTextureView.get(), // The terminal contents
_customShaderTextureView.get(), // the experimental.pixelShaderImagePath, if there is one
};
p.deviceContext->PSSetShaderResources(0, resourceViews[1] ? 2 : 1, &resourceViews[0]);
p.deviceContext->PSSetSamplers(0, 1, _customShaderSamplerState.addressof());

// OM: Output Merger
Expand Down
2 changes: 2 additions & 0 deletions src/renderer/atlas/BackendD3D.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,8 @@ namespace Microsoft::Console::Render::Atlas
wil::com_ptr<ID3D11PixelShader> _customPixelShader;
wil::com_ptr<ID3D11Buffer> _customShaderConstantBuffer;
wil::com_ptr<ID3D11SamplerState> _customShaderSamplerState;
wil::com_ptr<ID3D11Texture2D> _customShaderTexture;
wil::com_ptr<ID3D11ShaderResourceView> _customShaderTextureView;
std::chrono::steady_clock::time_point _customShaderStartTime;

wil::com_ptr<ID3D11Texture2D> _backgroundBitmap;
Expand Down
5 changes: 3 additions & 2 deletions src/renderer/atlas/atlas.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<Import Project="$(SolutionDir)src\common.build.pre.props" />
<Import Project="$(SolutionDir)src\common.nugetversions.props" />
<ItemGroup>
<ClCompile Include="AtlasEngine.cpp" />
<ClCompile Include="AtlasEngine.api.cpp" />
<ClCompile Include="AtlasEngine.r.cpp" />
<ClCompile Include="Backend.cpp" />
Expand All @@ -22,10 +23,11 @@
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="AtlasEngine.cpp" />
<ClCompile Include="stb_rect_pack.cpp" />
<ClCompile Include="wic.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="AtlasEngine.h" />
<ClInclude Include="Backend.h" />
<ClInclude Include="BackendD2D.h" />
<ClInclude Include="BackendD3D.h" />
Expand All @@ -35,7 +37,6 @@
<ClInclude Include="dwrite.h" />
<ClInclude Include="DWriteTextAnalysis.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="AtlasEngine.h" />
<ClInclude Include="wic.h" />
</ItemGroup>
<ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions src/renderer/atlas/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ namespace Microsoft::Console::Render::Atlas
u32 backgroundColor = 0;
u32 selectionColor = 0x7fffffff;
std::wstring customPixelShaderPath;
std::wstring customPixelShaderImagePath;
bool useRetroTerminalEffect = false;
};

Expand Down
1 change: 1 addition & 0 deletions src/renderer/atlas/pch.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <dxgi1_3.h>
#include <dxgidebug.h>
#include <VersionHelpers.h>
#include <wincodec.h>

#include <gsl/gsl_util>
#include <gsl/pointers>
Expand Down
Loading
Loading