Offset background texture and use Sample() instead of Load()

This commit is contained in:
Leonard Hecker
2023-08-12 02:04:48 +02:00
committed by Dustin L. Howett
parent eec8dbd6d7
commit 2a58b001bf
4 changed files with 52 additions and 20 deletions

View File

@@ -571,19 +571,30 @@ void BackendD3D::_recreateBackgroundColorBitmap(const RenderingPayload& p)
_backgroundBitmapGeneration = {};
}
void BackendD3D::_recreateConstBuffer(const RenderingPayload& p) const
void BackendD3D::_recreateConstBuffer(const RenderingPayload& p)
{
{
VSConstBuffer data{};
data.positionScale = { 2.0f / p.s->targetSize.x, -2.0f / p.s->targetSize.y };
data.padding = { p.s->misc->topLeftOffset.x, p.s->misc->topLeftOffset.y, 0.f, 0.f };
data.positionScale = {
2.0f / p.s->targetSize.x,
-2.0f / p.s->targetSize.y,
};
data.positionOffset = {
data.positionScale.x * p.s->misc->topLeftOffset.x - 1.0f,
data.positionScale.y * p.s->misc->topLeftOffset.y + 1.0f,
};
p.deviceContext->UpdateSubresource(_vsConstantBuffer.get(), 0, nullptr, &data, 0, 0);
}
{
PSConstBuffer data{};
data.backgroundColor = colorFromU32Premultiply<f32x4>(p.s->misc->backgroundColor);
data.backgroundCellSize = { static_cast<f32>(p.s->font->cellSize.x), static_cast<f32>(p.s->font->cellSize.y) };
data.backgroundCellCount = { static_cast<f32>(p.s->viewportCellCount.x), static_cast<f32>(p.s->viewportCellCount.y) };
data.viewportScale = {
1.0f / (p.s->font->cellSize.x * p.s->viewportCellCount.x),
1.0f / (p.s->font->cellSize.y * p.s->viewportCellCount.y),
};
data.viewportOffset = {
data.viewportScale.x * -p.s->misc->topLeftOffset.x,
data.viewportScale.y * -p.s->misc->topLeftOffset.y,
};
DWrite_GetGammaRatios(_gamma, data.gammaRatios);
data.enhancedContrast = p.s->font->antialiasingMode == AntialiasingMode::ClearType ? _cleartypeEnhancedContrast : _grayscaleEnhancedContrast;
data.underlineWidth = p.s->font->underline.height;
@@ -595,6 +606,23 @@ void BackendD3D::_recreateConstBuffer(const RenderingPayload& p) const
data.shadedGlyphDotSize = std::max(1.0f, std::roundf(std::max(p.s->font->cellSize.x / 12.0f, p.s->font->cellSize.y / 24.0f)));
p.deviceContext->UpdateSubresource(_psConstantBuffer.get(), 0, nullptr, &data, 0, 0);
}
{
const auto color = colorFromU32Premultiply<f32x4>(p.s->misc->backgroundColor);
const D3D11_SAMPLER_DESC desc{
.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT,
.AddressU = D3D11_TEXTURE_ADDRESS_BORDER,
.AddressV = D3D11_TEXTURE_ADDRESS_BORDER,
.AddressW = D3D11_TEXTURE_ADDRESS_BORDER,
.MipLODBias = 0,
.MaxAnisotropy = 1,
.ComparisonFunc = D3D11_COMPARISON_NEVER,
//.BorderColor = { color.x, color.y, color.z, color.w },
.BorderColor = { 1.0f, 0.2f, 0.2f, 1.0f },
.MinLOD = -FLT_MAX,
.MaxLOD = FLT_MAX,
};
THROW_IF_FAILED(p.device->CreateSamplerState(&desc, _backgroundSampler.put()));
}
}
void BackendD3D::_setupDeviceContextState(const RenderingPayload& p)
@@ -623,6 +651,7 @@ void BackendD3D::_setupDeviceContextState(const RenderingPayload& p)
p.deviceContext->PSSetShader(_pixelShader.get(), nullptr, 0);
p.deviceContext->PSSetConstantBuffers(0, 1, _psConstantBuffer.addressof());
p.deviceContext->PSSetShaderResources(0, 2, &resources[0]);
p.deviceContext->PSSetSamplers(0, 1, _backgroundSampler.addressof());
// OM: Output Merger
p.deviceContext->OMSetBlendState(_blendState.get(), nullptr, 0xffffffff);
@@ -1073,6 +1102,10 @@ void BackendD3D::_drawBackground(const RenderingPayload& p)
_appendQuad() = {
.shadingType = static_cast<u16>(ShadingType::Background),
.position = {
static_cast<i16>(lrintf(-p.s->misc->topLeftOffset.x)),
static_cast<i16>(lrintf(-p.s->misc->topLeftOffset.x)),
},
.size = p.s->targetSize,
};
}
@@ -2373,7 +2406,7 @@ void BackendD3D::_executeCustomShader(RenderingPayload& p)
p.deviceContext->PSSetShader(_pixelShader.get(), nullptr, 0);
p.deviceContext->PSSetConstantBuffers(0, 1, _psConstantBuffer.addressof());
p.deviceContext->PSSetShaderResources(0, 2, &resources[0]);
p.deviceContext->PSSetSamplers(0, 0, nullptr);
p.deviceContext->PSSetSamplers(0, 1, _backgroundSampler.addressof());
// OM: Output Merger
p.deviceContext->OMSetBlendState(_blendState.get(), nullptr, 0xffffffff);

View File

@@ -29,17 +29,16 @@ namespace Microsoft::Console::Render::Atlas
// padding so that it is {u32; u32; u32; <4 byte padding>; u32x2}.
// * bool will probably not work the way you want it to,
// because HLSL uses 32-bit bools and C++ doesn't.
alignas(sizeof(f32x4)) f32x4 padding;
alignas(sizeof(f32x2)) f32x2 positionScale;
alignas(sizeof(f32x2)) f32x2 positionOffset;
#pragma warning(suppress : 4324) // 'VSConstBuffer': structure was padded due to alignment specifier
};
// WARNING: Same rules as for VSConstBuffer above apply.
struct alignas(16) PSConstBuffer
{
alignas(sizeof(f32x4)) f32x4 backgroundColor;
alignas(sizeof(f32x2)) f32x2 backgroundCellSize;
alignas(sizeof(f32x2)) f32x2 backgroundCellCount;
alignas(sizeof(f32x2)) f32x2 backgroundScale;
alignas(sizeof(f32x2)) f32x2 backgroundOffset;
alignas(sizeof(f32x4)) f32 gammaRatios[4]{};
alignas(sizeof(f32)) f32 enhancedContrast = 0;
alignas(sizeof(f32)) f32 underlineWidth = 0;
@@ -231,7 +230,7 @@ namespace Microsoft::Console::Render::Atlas
void _recreateCustomShader(const RenderingPayload& p);
void _recreateCustomRenderTargetView(const RenderingPayload& p);
void _recreateBackgroundColorBitmap(const RenderingPayload& p);
void _recreateConstBuffer(const RenderingPayload& p) const;
void _recreateConstBuffer(const RenderingPayload& p);
void _setupDeviceContextState(const RenderingPayload& p);
void _debugUpdateShaders(const RenderingPayload& p) noexcept;
void _debugShowDirty(const RenderingPayload& p);
@@ -292,6 +291,7 @@ namespace Microsoft::Console::Render::Atlas
wil::com_ptr<ID3D11Texture2D> _backgroundBitmap;
wil::com_ptr<ID3D11ShaderResourceView> _backgroundBitmapView;
wil::com_ptr<ID3D11SamplerState> _backgroundSampler;
til::generation_t _backgroundBitmapGeneration;
wil::com_ptr<ID3D11Texture2D> _glyphAtlas;

View File

@@ -6,9 +6,8 @@
cbuffer ConstBuffer : register(b0)
{
float4 backgroundColor;
float2 backgroundCellSize;
float2 backgroundCellCount;
float2 backgroundScale;
float2 backgroundOffset;
float4 gammaRatios;
float enhancedContrast;
float underlineWidth;
@@ -17,6 +16,7 @@ cbuffer ConstBuffer : register(b0)
float shadedGlyphDotSize;
}
SamplerState backgroundSampler;
Texture2D<float4> background : register(t0);
Texture2D<float4> glyphAtlas : register(t1);
@@ -37,8 +37,7 @@ Output main(PSData data) : SV_Target
{
case SHADING_TYPE_TEXT_BACKGROUND:
{
float2 cell = data.position.xy / backgroundCellSize;
color = all(cell < backgroundCellCount) ? background[cell] : backgroundColor;
color = background.Sample(backgroundSampler, data.position.xy * backgroundScale + backgroundOffset);
weights = float4(1, 1, 1, 1);
break;
}

View File

@@ -5,8 +5,8 @@
cbuffer ConstBuffer : register(b0)
{
float4 padding;
float2 positionScale;
float2 positionOffset;
}
// clang-format off
@@ -19,8 +19,8 @@ PSData main(VSData data)
output.renditionScale = data.renditionScale;
// positionScale is expected to be float2(2.0f / sizeInPixel.x, -2.0f / sizeInPixel.y). Together with the
// addition below this will transform our "position" from pixel into normalized device coordinate (NDC) space.
output.position.xy = (padding.xy + data.position + data.vertex.xy * data.size) * positionScale + float2(-1.0f, 1.0f);
output.position.xy = (data.vertex * data.size + data.position) * positionScale + positionOffset;
output.position.zw = float2(0, 1);
output.texcoord = data.texcoord + data.vertex.xy * data.size;
output.texcoord = data.vertex * data.size + data.texcoord;
return output;
}