mirror of
https://github.com/Dingo-Shenanigans/ReSkate.git
synced 2026-10-27 02:46:41 +01:00
Merge pull request #177 from ValveTextureFile/shader-macos-fixing
Launcher/overlay: fall back to ImGui's stock pixel shader when the HDR one can't be built
This commit is contained in:
4 files changed
+87
-53
No files matched your search
@@ -401,6 +401,9 @@ bool setup_graphics() {
|
||||
// Font upload uses the exact swapchain queue, and this pinned backend waits
|
||||
// for its own upload fence before returning from device-object creation.
|
||||
const bool objects = s.dx12_ready && ImGui_ImplDX12_CreateDeviceObjects();
|
||||
if (objects && !ImGui_ImplDX12_HasOutputTransfer())
|
||||
dingosdk::logging::write(dingosdk::logging::Level::warning, dingosdk::logging::Channel::graphics,
|
||||
"Overlay output: this system could not build the HDR-aware shader; drawing in SDR, so an HDR game shows the overlay off-colour.");
|
||||
ImGui::SetCurrentContext(previous);
|
||||
if (!objects) {
|
||||
dingosdk::logging::printf(dingosdk::logging::Level::error, dingosdk::logging::Channel::graphics, "Graphics setup failed in ImGui initialization: win32=%d dx12=%d objects=%d",
|
||||
|
||||
+78
-53
@@ -121,6 +121,11 @@ void ImGui_ImplDX12_SetOutputTransfer(int mode, float white_nits)
|
||||
g_ReSkateOutputTransfer[0] = (float)mode;
|
||||
g_ReSkateOutputTransfer[1] = white_nits;
|
||||
}
|
||||
static bool g_ReSkateOutputTransferAvailable = false;
|
||||
bool ImGui_ImplDX12_HasOutputTransfer()
|
||||
{
|
||||
return g_ReSkateOutputTransferAvailable;
|
||||
}
|
||||
|
||||
// Functions
|
||||
static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12GraphicsCommandList* command_list, ImGui_ImplDX12_RenderBuffers* fr)
|
||||
@@ -536,7 +541,6 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
||||
psoDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE;
|
||||
|
||||
ID3DBlob* vertexShaderBlob;
|
||||
ID3DBlob* pixelShaderBlob;
|
||||
|
||||
// Create the vertex shader
|
||||
{
|
||||
@@ -582,55 +586,6 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
||||
psoDesc.InputLayout = { local_layout, 3 };
|
||||
}
|
||||
|
||||
// Create the pixel shader
|
||||
{
|
||||
static const char* pixelShader =
|
||||
"struct PS_INPUT\
|
||||
{\
|
||||
float4 pos : SV_POSITION;\
|
||||
float4 col : COLOR0;\
|
||||
float2 uv : TEXCOORD0;\
|
||||
};\
|
||||
cbuffer vertexBuffer : register(b0) \
|
||||
{\
|
||||
float4x4 ProjectionMatrix; \
|
||||
float4 OutputTransfer; \
|
||||
};\
|
||||
SamplerState sampler0 : register(s0);\
|
||||
Texture2D texture0 : register(t0);\
|
||||
\
|
||||
float3 srgb_to_linear(float3 c)\
|
||||
{\
|
||||
return lerp(c / 12.92, pow(abs((c + 0.055) / 1.055), 2.4), step(0.04045, c)); \
|
||||
}\
|
||||
float4 main(PS_INPUT input) : SV_Target\
|
||||
{\
|
||||
float4 out_col = input.col * texture0.Sample(sampler0, input.uv); \
|
||||
if (OutputTransfer.x > 0.5) \
|
||||
{\
|
||||
float3 lin = srgb_to_linear(saturate(out_col.rgb)); \
|
||||
if (OutputTransfer.x < 1.5) \
|
||||
{\
|
||||
out_col.rgb = lin * (OutputTransfer.y / 80.0); \
|
||||
}\
|
||||
else \
|
||||
{\
|
||||
float3 wide = float3(dot(lin, float3(0.6274, 0.3293, 0.0433)), dot(lin, float3(0.0691, 0.9195, 0.0114)), dot(lin, float3(0.0164, 0.0880, 0.8956))); \
|
||||
float3 y = pow(saturate(wide * (OutputTransfer.y / 10000.0)), 0.1593017578125); \
|
||||
out_col.rgb = pow((0.8359375 + 18.8515625 * y) / (1.0 + 18.6875 * y), 78.84375); \
|
||||
}\
|
||||
}\
|
||||
return out_col; \
|
||||
}";
|
||||
|
||||
if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), nullptr, nullptr, nullptr, "main", "ps_5_0", 0, 0, &pixelShaderBlob, nullptr)))
|
||||
{
|
||||
vertexShaderBlob->Release();
|
||||
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||
}
|
||||
psoDesc.PS = { pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize() };
|
||||
}
|
||||
|
||||
// Create the blending setup
|
||||
{
|
||||
D3D12_BLEND_DESC& desc = psoDesc.BlendState;
|
||||
@@ -673,10 +628,80 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
||||
desc.BackFace = desc.FrontFace;
|
||||
}
|
||||
|
||||
HRESULT result_pipeline_state = bd->pd3dDevice->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&bd->pPipelineState));
|
||||
// Create the pixel shader and the pipeline
|
||||
// [ReSkate] The HDR-aware shader first, then ImGui's stock one. Some D3DCompile()s cannot build the HDR one (Wine's
|
||||
// builtin d3dcompiler, as under Apple's Game Porting Toolkit), and an SDR-only window beats no window at all.
|
||||
{
|
||||
static const char* pixelShaders[] =
|
||||
{
|
||||
"struct PS_INPUT\
|
||||
{\
|
||||
float4 pos : SV_POSITION;\
|
||||
float4 col : COLOR0;\
|
||||
float2 uv : TEXCOORD0;\
|
||||
};\
|
||||
cbuffer vertexBuffer : register(b0) \
|
||||
{\
|
||||
float4x4 ProjectionMatrix; \
|
||||
float4 OutputTransfer; \
|
||||
};\
|
||||
SamplerState sampler0 : register(s0);\
|
||||
Texture2D texture0 : register(t0);\
|
||||
\
|
||||
float3 srgb_to_linear(float3 c)\
|
||||
{\
|
||||
return lerp(c / 12.92, pow(abs((c + 0.055) / 1.055), 2.4), step(0.04045, c)); \
|
||||
}\
|
||||
float4 main(PS_INPUT input) : SV_Target\
|
||||
{\
|
||||
float4 out_col = input.col * texture0.Sample(sampler0, input.uv); \
|
||||
if (OutputTransfer.x > 0.5) \
|
||||
{\
|
||||
float3 lin = srgb_to_linear(saturate(out_col.rgb)); \
|
||||
if (OutputTransfer.x < 1.5) \
|
||||
{\
|
||||
out_col.rgb = lin * (OutputTransfer.y / 80.0); \
|
||||
}\
|
||||
else \
|
||||
{\
|
||||
float3 wide = float3(dot(lin, float3(0.6274, 0.3293, 0.0433)), dot(lin, float3(0.0691, 0.9195, 0.0114)), dot(lin, float3(0.0164, 0.0880, 0.8956))); \
|
||||
float3 y = pow(saturate(wide * (OutputTransfer.y / 10000.0)), 0.1593017578125); \
|
||||
out_col.rgb = pow((0.8359375 + 18.8515625 * y) / (1.0 + 18.6875 * y), 78.84375); \
|
||||
}\
|
||||
}\
|
||||
return out_col; \
|
||||
}",
|
||||
"struct PS_INPUT\
|
||||
{\
|
||||
float4 pos : SV_POSITION;\
|
||||
float4 col : COLOR0;\
|
||||
float2 uv : TEXCOORD0;\
|
||||
};\
|
||||
SamplerState sampler0 : register(s0);\
|
||||
Texture2D texture0 : register(t0);\
|
||||
\
|
||||
float4 main(PS_INPUT input) : SV_Target\
|
||||
{\
|
||||
float4 out_col = input.col * texture0.Sample(sampler0, input.uv); \
|
||||
return out_col; \
|
||||
}",
|
||||
};
|
||||
|
||||
g_ReSkateOutputTransferAvailable = false;
|
||||
for (int i = 0; i < IM_ARRAYSIZE(pixelShaders) && bd->pPipelineState == nullptr; i++)
|
||||
{
|
||||
ID3DBlob* pixelShaderBlob = nullptr;
|
||||
if (FAILED(D3DCompile(pixelShaders[i], strlen(pixelShaders[i]), nullptr, nullptr, nullptr, "main", "ps_5_0", 0, 0, &pixelShaderBlob, nullptr)))
|
||||
continue; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||
psoDesc.PS = { pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize() };
|
||||
if (bd->pd3dDevice->CreateGraphicsPipelineState(&psoDesc, IID_PPV_ARGS(&bd->pPipelineState)) != S_OK)
|
||||
bd->pPipelineState = nullptr;
|
||||
pixelShaderBlob->Release();
|
||||
g_ReSkateOutputTransferAvailable = bd->pPipelineState != nullptr && i == 0;
|
||||
}
|
||||
}
|
||||
vertexShaderBlob->Release();
|
||||
pixelShaderBlob->Release();
|
||||
if (result_pipeline_state != S_OK)
|
||||
if (bd->pPipelineState == nullptr)
|
||||
return false;
|
||||
|
||||
return ImGui_ImplDX12_CreateFontsTexture();
|
||||
|
||||
+3
@@ -56,6 +56,9 @@ IMGUI_IMPL_API void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3
|
||||
// primaries with the ST.2084 (PQ) curve (a 10-bit HDR target). `white_nits`: how bright white
|
||||
// is drawn in 1 and 2. Read at each ImGui_ImplDX12_RenderDrawData.
|
||||
IMGUI_IMPL_API void ImGui_ImplDX12_SetOutputTransfer(int mode, float white_nits);
|
||||
// [ReSkate] Whether the pipeline made by the last ImGui_ImplDX12_CreateDeviceObjects() applies that transfer. False when
|
||||
// D3DCompile() or the driver could not build the HDR-aware shader and ImGui's stock (SDR) one is drawing instead.
|
||||
IMGUI_IMPL_API bool ImGui_ImplDX12_HasOutputTransfer();
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
// Legacy initialization API Obsoleted in 1.91.5
|
||||
|
||||
@@ -127,6 +127,9 @@ bool Renderer::init(HWND window) {
|
||||
"Launcher renderer: this driver cannot create the Direct3D 12 pipeline the window draws with.");
|
||||
return false;
|
||||
}
|
||||
if (!ImGui_ImplDX12_HasOutputTransfer())
|
||||
logging::write(logging::Level::info, logging::Channel::launcher,
|
||||
"Launcher renderer: drawing with ImGui's stock shader; this system could not build the HDR-aware one.");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user