mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-31 21:03:43 +01:00
DrawListTextureWrap: use two textures (#2285)
Making premultiplied pixel data into straight alpha in-place using UAV seems to be not working on older graphics cards. Now every instance of DrawListTextureWrap keeps two GPU textures, where one keeps a premultiplied data which will be written to using ImGui draw data and read from to calculate straight alpha pixel data.
This commit is contained in:
parent
d80202a755
commit
e415699bb3
8 changed files with 47 additions and 30 deletions
|
|
@ -26,7 +26,10 @@ internal sealed unsafe partial class DrawListTextureWrap : IDrawListTextureWrap,
|
|||
private ComPtr<ID3D11Texture2D> tex;
|
||||
private ComPtr<ID3D11ShaderResourceView> srv;
|
||||
private ComPtr<ID3D11RenderTargetView> rtv;
|
||||
private ComPtr<ID3D11UnorderedAccessView> uav;
|
||||
|
||||
private ComPtr<ID3D11Texture2D> texPremultiplied;
|
||||
private ComPtr<ID3D11ShaderResourceView> srvPremultiplied;
|
||||
private ComPtr<ID3D11RenderTargetView> rtvPremultiplied;
|
||||
|
||||
private int width;
|
||||
private int height;
|
||||
|
|
@ -138,7 +141,9 @@ internal sealed unsafe partial class DrawListTextureWrap : IDrawListTextureWrap,
|
|||
this.srv.Reset();
|
||||
this.tex.Reset();
|
||||
this.rtv.Reset();
|
||||
this.uav.Reset();
|
||||
this.srvPremultiplied.Reset();
|
||||
this.texPremultiplied.Reset();
|
||||
this.rtvPremultiplied.Reset();
|
||||
this.device.Reset();
|
||||
this.deviceContext.Reset();
|
||||
|
||||
|
|
@ -180,7 +185,7 @@ internal sealed unsafe partial class DrawListTextureWrap : IDrawListTextureWrap,
|
|||
|
||||
// Clear the texture first, as the texture exists.
|
||||
var clearColor = this.ClearColor;
|
||||
this.deviceContext.Get()->ClearRenderTargetView(this.rtv.Get(), (float*)&clearColor);
|
||||
this.deviceContext.Get()->ClearRenderTargetView(this.rtvPremultiplied.Get(), (float*)&clearColor);
|
||||
|
||||
// If there is nothing to draw, then stop.
|
||||
if (!drawData.Valid
|
||||
|
|
@ -196,8 +201,8 @@ internal sealed unsafe partial class DrawListTextureWrap : IDrawListTextureWrap,
|
|||
|
||||
using (new DeviceContextStateBackup(this.device.Get()->GetFeatureLevel(), this.deviceContext))
|
||||
{
|
||||
Service<Renderer>.Get().RenderDrawData(this.rtv.Get(), drawData);
|
||||
Service<Renderer>.Get().MakeStraight(this.uav.Get());
|
||||
Service<Renderer>.Get().RenderDrawData(this.rtvPremultiplied.Get(), drawData);
|
||||
Service<Renderer>.Get().MakeStraight(this.srvPremultiplied.Get(), this.rtv.Get());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -217,7 +222,9 @@ internal sealed unsafe partial class DrawListTextureWrap : IDrawListTextureWrap,
|
|||
this.tex.Reset();
|
||||
this.srv.Reset();
|
||||
this.rtv.Reset();
|
||||
this.uav.Reset();
|
||||
this.texPremultiplied.Reset();
|
||||
this.srvPremultiplied.Reset();
|
||||
this.rtvPremultiplied.Reset();
|
||||
this.width = newWidth;
|
||||
this.Height = newHeight;
|
||||
this.srv = new((ID3D11ShaderResourceView*)this.emptyTexture.ImGuiHandle);
|
||||
|
|
@ -231,7 +238,9 @@ internal sealed unsafe partial class DrawListTextureWrap : IDrawListTextureWrap,
|
|||
using var tmptex = default(ComPtr<ID3D11Texture2D>);
|
||||
using var tmpsrv = default(ComPtr<ID3D11ShaderResourceView>);
|
||||
using var tmprtv = default(ComPtr<ID3D11RenderTargetView>);
|
||||
using var tmpuav = default(ComPtr<ID3D11UnorderedAccessView>);
|
||||
using var tmptexPremultiplied = default(ComPtr<ID3D11Texture2D>);
|
||||
using var tmpsrvPremultiplied = default(ComPtr<ID3D11ShaderResourceView>);
|
||||
using var tmprtvPremultiplied = default(ComPtr<ID3D11RenderTargetView>);
|
||||
|
||||
var tmpTexDesc = new D3D11_TEXTURE2D_DESC
|
||||
{
|
||||
|
|
@ -243,8 +252,7 @@ internal sealed unsafe partial class DrawListTextureWrap : IDrawListTextureWrap,
|
|||
SampleDesc = new(1, 0),
|
||||
Usage = D3D11_USAGE.D3D11_USAGE_DEFAULT,
|
||||
BindFlags = (uint)(D3D11_BIND_FLAG.D3D11_BIND_SHADER_RESOURCE |
|
||||
D3D11_BIND_FLAG.D3D11_BIND_RENDER_TARGET |
|
||||
D3D11_BIND_FLAG.D3D11_BIND_UNORDERED_ACCESS),
|
||||
D3D11_BIND_FLAG.D3D11_BIND_RENDER_TARGET),
|
||||
CPUAccessFlags = 0u,
|
||||
MiscFlags = 0u,
|
||||
};
|
||||
|
|
@ -263,15 +271,27 @@ internal sealed unsafe partial class DrawListTextureWrap : IDrawListTextureWrap,
|
|||
if (hr.FAILED)
|
||||
return hr;
|
||||
|
||||
var uavDesc = new D3D11_UNORDERED_ACCESS_VIEW_DESC(tmptex, D3D11_UAV_DIMENSION.D3D11_UAV_DIMENSION_TEXTURE2D);
|
||||
hr = this.device.Get()->CreateUnorderedAccessView(tmpres, &uavDesc, tmpuav.GetAddressOf());
|
||||
hr = this.device.Get()->CreateTexture2D(&tmpTexDesc, null, tmptexPremultiplied.GetAddressOf());
|
||||
if (hr.FAILED)
|
||||
return hr;
|
||||
|
||||
tmpres = (ID3D11Resource*)tmptexPremultiplied.Get();
|
||||
srvDesc = new(tmptexPremultiplied, D3D_SRV_DIMENSION.D3D11_SRV_DIMENSION_TEXTURE2D);
|
||||
hr = this.device.Get()->CreateShaderResourceView(tmpres, &srvDesc, tmpsrvPremultiplied.GetAddressOf());
|
||||
if (hr.FAILED)
|
||||
return hr;
|
||||
|
||||
rtvDesc = new(tmptexPremultiplied, D3D11_RTV_DIMENSION.D3D11_RTV_DIMENSION_TEXTURE2D);
|
||||
hr = this.device.Get()->CreateRenderTargetView(tmpres, &rtvDesc, tmprtvPremultiplied.GetAddressOf());
|
||||
if (hr.FAILED)
|
||||
return hr;
|
||||
|
||||
tmptex.Swap(ref this.tex);
|
||||
tmpsrv.Swap(ref this.srv);
|
||||
tmprtv.Swap(ref this.rtv);
|
||||
tmpuav.Swap(ref this.uav);
|
||||
tmptexPremultiplied.Swap(ref this.texPremultiplied);
|
||||
tmpsrvPremultiplied.Swap(ref this.srvPremultiplied);
|
||||
tmprtvPremultiplied.Swap(ref this.rtvPremultiplied);
|
||||
this.width = newWidth;
|
||||
this.height = newHeight;
|
||||
this.format = newFormat;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#include "DrawListTexture.Renderer.Common.hlsl"
|
||||
#include "Renderer.Common.hlsl"
|
||||
|
||||
struct ImDrawVert {
|
||||
float2 position : POSITION;
|
||||
|
|
@ -18,7 +18,6 @@ struct PsData {
|
|||
|
||||
Texture2D s_texture : register(t0);
|
||||
SamplerState s_sampler : register(s0);
|
||||
RWTexture2D<float4> s_output : register(u1);
|
||||
|
||||
VsData vs_main(const ImDrawVert idv) {
|
||||
VsData result;
|
||||
|
|
@ -34,7 +33,7 @@ float4 ps_main(const VsData vd) : SV_TARGET {
|
|||
|
||||
/*
|
||||
|
||||
fxc /Zi /T vs_5_0 /E vs_main /Fo DrawListTexture.Renderer.DrawToPremul.vs.bin DrawListTexture.Renderer.DrawToPremul.hlsl
|
||||
fxc /Zi /T ps_5_0 /E ps_main /Fo DrawListTexture.Renderer.DrawToPremul.ps.bin DrawListTexture.Renderer.DrawToPremul.hlsl
|
||||
fxc /Zi /T vs_5_0 /E vs_main /Fo Renderer.DrawToPremul.vs.bin Renderer.DrawToPremul.hlsl
|
||||
fxc /Zi /T ps_5_0 /E ps_main /Fo Renderer.DrawToPremul.ps.bin Renderer.DrawToPremul.hlsl
|
||||
|
||||
*/
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -1,22 +1,19 @@
|
|||
RWTexture2D<unorm float4> s_output : register(u1);
|
||||
Texture2D s_texture : register(t0);
|
||||
|
||||
float4 vs_main(const float2 position : POSITION) : SV_POSITION {
|
||||
return float4(position, 0, 1);
|
||||
}
|
||||
|
||||
float4 ps_main(const float4 position : SV_POSITION) : SV_TARGET {
|
||||
const float4 src = s_output[position.xy];
|
||||
s_output[position.xy] =
|
||||
src.a > 0
|
||||
const float4 src = s_texture[position.xy];
|
||||
return src.a > 0
|
||||
? float4(src.rgb / src.a, src.a)
|
||||
: float4(0, 0, 0, 0);
|
||||
|
||||
return float4(0, 0, 0, 0); // unused
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
fxc /Zi /T vs_5_0 /E vs_main /Fo DrawListTexture.Renderer.MakeStraight.vs.bin DrawListTexture.Renderer.MakeStraight.hlsl
|
||||
fxc /Zi /T ps_5_0 /E ps_main /Fo DrawListTexture.Renderer.MakeStraight.ps.bin DrawListTexture.Renderer.MakeStraight.hlsl
|
||||
fxc /Zi /T vs_5_0 /E vs_main /Fo Renderer.MakeStraight.vs.bin Renderer.MakeStraight.hlsl
|
||||
fxc /Zi /T ps_5_0 /E ps_main /Fo Renderer.MakeStraight.ps.bin Renderer.MakeStraight.hlsl
|
||||
|
||||
*/
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
|
@ -259,15 +259,16 @@ internal sealed unsafe partial class DrawListTextureWrap
|
|||
}
|
||||
|
||||
/// <summary>Renders draw data.</summary>
|
||||
/// <param name="puav">The pointer to a Texture2D UAV to make straight.</param>
|
||||
public void MakeStraight(ID3D11UnorderedAccessView* puav)
|
||||
/// <param name="psrv">The pointer to a Texture2D SRV to read premultiplied data from.</param>
|
||||
/// <param name="prtv">The pointer to a Texture2D RTV to write straightened data.</param>
|
||||
public void MakeStraight(ID3D11ShaderResourceView* psrv, ID3D11RenderTargetView* prtv)
|
||||
{
|
||||
ThreadSafety.AssertMainThread();
|
||||
|
||||
D3D11_TEXTURE2D_DESC texDesc;
|
||||
using (var texRes = default(ComPtr<ID3D11Resource>))
|
||||
{
|
||||
puav->GetResource(texRes.GetAddressOf());
|
||||
prtv->GetResource(texRes.GetAddressOf());
|
||||
|
||||
using var tex = default(ComPtr<ID3D11Texture2D>);
|
||||
texRes.As(&tex).ThrowOnError();
|
||||
|
|
@ -292,10 +293,9 @@ internal sealed unsafe partial class DrawListTextureWrap
|
|||
var viewport = new D3D11_VIEWPORT(0, 0, texDesc.Width, texDesc.Height);
|
||||
this.deviceContext.Get()->RSSetViewports(1, &viewport);
|
||||
|
||||
this.deviceContext.Get()->OMSetBlendState(null, null, 0xFFFFFFFF);
|
||||
this.deviceContext.Get()->OMSetBlendState(null, null, 0xffffffff);
|
||||
this.deviceContext.Get()->OMSetDepthStencilState(this.depthStencilState, 0);
|
||||
var nullrtv = default(ID3D11RenderTargetView*);
|
||||
this.deviceContext.Get()->OMSetRenderTargetsAndUnorderedAccessViews(1, &nullrtv, null, 1, 1, &puav, null);
|
||||
this.deviceContext.Get()->OMSetRenderTargets(1, &prtv, null);
|
||||
|
||||
this.deviceContext.Get()->VSSetShader(this.makeStraightVertexShader.Get(), null, 0);
|
||||
this.deviceContext.Get()->PSSetShader(this.makeStraightPixelShader.Get(), null, 0);
|
||||
|
|
@ -304,6 +304,7 @@ internal sealed unsafe partial class DrawListTextureWrap
|
|||
this.deviceContext.Get()->DSSetShader(null, null, 0);
|
||||
this.deviceContext.Get()->CSSetShader(null, null, 0);
|
||||
|
||||
this.deviceContext.Get()->PSSetShaderResources(0, 1, &psrv);
|
||||
this.deviceContext.Get()->DrawIndexed(6, 0, 0);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue