Created
December 14, 2020 23:58
-
-
Save Andon13/ec0f3f992c09977449313e711793cf07 to your computer and use it in GitHub Desktop.
Valve, let's stop being stupid here. I've patched your overlay a number of times for HDR... Please work with me to get this patched, or let me render your overlay instead of you.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if ((SK_GetCurrentRenderBackend ().api == SK_RenderAPI::D3D12) && type == sk_shader_class::Pixel && checksum == 0x9aefe985) | |
{ | |
extern std::string | |
__SK_MakeSteamPS ( bool hdr10, | |
bool scRGB, | |
float max_luma ); | |
extern | |
ID3D10Blob* | |
__SK_MakeSteamPS_Bytecode ( bool hdr10, | |
bool scRGB, | |
float max_luma ); | |
extern bool __SK_HDR_16BitSwap; | |
if ( __SK_HDR_16BitSwap || ( SK_GetCurrentRenderBackend ().hdr_capable && | |
SK_GetCurrentRenderBackend ().scanout.dxgi_colorspace == DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709 )) | |
{ | |
static std::string steam_ps_scRGB = | |
__SK_MakeSteamPS (false, true, 750.0f / 80.0f); | |
dll_log->Log ( L" Steam Replacement Pixel Shader <scRGB 750.0 nits>: %hs", | |
steam_ps_scRGB.c_str () ); | |
static ID3D10Blob* steam_blob_scRGB = | |
__SK_MakeSteamPS_Bytecode (false, true, 750.0f / 80.0f); | |
pShaderBytecode = steam_blob_scRGB->GetBufferPointer (); | |
BytecodeLength = steam_blob_scRGB->GetBufferSize (); | |
} | |
else if ( | |
( SK_GetCurrentRenderBackend ().hdr_capable && | |
SK_GetCurrentRenderBackend ().scanout.dxgi_colorspace == DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020 ) | |
) | |
{ | |
static std::string steam_ps_PQ = | |
__SK_MakeSteamPS (true, false, 750.0f); | |
dll_log->Log ( L" Steam Replacement Pixel Shader <PQ 750.0 nits>: %hs", | |
steam_ps_PQ.c_str () ); | |
static ID3D10Blob* steam_blob_PQ = | |
__SK_MakeSteamPS_Bytecode (true, false, 750.0f); | |
pShaderBytecode = steam_blob_PQ->GetBufferPointer (); | |
BytecodeLength = steam_blob_PQ->GetBufferSize (); | |
} | |
} | |
hr = | |
InvokeCreateRoutine (); | |
/** | |
* This file is part of Special K. | |
* | |
* Special K is free software : you can redistribute it | |
* and/or modify it under the terms of the GNU General Public License | |
* as published by The Free Software Foundation, either version 3 of | |
* the License, or (at your option) any later version. | |
* | |
* Special K is distributed in the hope that it will be useful, | |
* | |
* But WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
* GNU General Public License for more details. | |
* | |
* You should have received a copy of the GNU General Public License | |
* along with Special K. | |
* | |
* If not, see <http://www.gnu.org/licenses/>. | |
* | |
**/ | |
#include <SpecialK/stdafx.h> | |
#ifdef __SK_SUBSYSTEM__ | |
#undef __SK_SUBSYSTEM__ | |
#endif | |
#define __SK_SUBSYSTEM__ L"DX12Shader" | |
namespace SK { | |
namespace D3D11On12 { | |
//--------------------- | |
class VertexShader { }; | |
class PixelShader { }; | |
//---------------------- | |
}; | |
}; | |
static std::string _SpecialNowhere; | |
template <typename _ShaderType> | |
struct ShaderBase | |
{ | |
_ShaderType *shader = nullptr; | |
ID3D10Blob *shaderBlob = nullptr; | |
bool assembleShaderString ( const char* szShaderString, | |
const wchar_t* wszShaderName, | |
const char* szEntryPoint, | |
const char* szShaderModel, | |
bool recompile = | |
false, | |
std::string& error_log = | |
_SpecialNowhere ) | |
{ | |
UNREFERENCED_PARAMETER (recompile); | |
UNREFERENCED_PARAMETER (error_log); | |
SK_ComPtr <ID3D10Blob> | |
messageBlob; | |
HRESULT hr = | |
D3DCompile ( szShaderString, | |
strlen (szShaderString), | |
nullptr, nullptr, nullptr, | |
szEntryPoint, szShaderModel, | |
0, 0, &shaderBlob, | |
&messageBlob ); | |
if (FAILED (hr)) | |
{ | |
if ( messageBlob != nullptr && | |
messageBlob->GetBufferSize () > 0 ) | |
{ | |
std::string | |
err; | |
err.reserve ( messageBlob->GetBufferSize () ); | |
err = ((char *)messageBlob->GetBufferPointer () ); | |
if (! err.empty ()) | |
{ | |
dll_log->LogEx ( | |
true, L"SK D3D11 Shader (SM=%hs) [%ws]: %hs", | |
szShaderModel, | |
wszShaderName, err.c_str () ); | |
} | |
} | |
return false; | |
} | |
return true; | |
#if 0 | |
HRESULT hrCompile = | |
DXGI_ERROR_NOT_CURRENTLY_AVAILABLE; | |
SK_ComQIPtr <ID3D11Device> | |
pDev ( | |
SK_GetCurrentRenderBackend ().device | |
); | |
if ( pDev != nullptr && | |
std::type_index ( typeid ( _ShaderType ) ) == | |
std::type_index ( typeid (ID3D11VertexShader) ) ) | |
{ | |
hrCompile = | |
pDev->CreateVertexShader ( | |
static_cast <DWORD *> ( shaderBlob->GetBufferPointer () ), | |
shaderBlob->GetBufferSize (), nullptr, | |
reinterpret_cast <ID3D11VertexShader **> | |
(&shader) | |
); | |
} | |
else if ( pDev != nullptr && | |
std::type_index ( typeid ( _ShaderType ) ) == | |
std::type_index ( typeid (ID3D11PixelShader) ) ) | |
{ | |
hrCompile = | |
pDev->CreatePixelShader ( | |
static_cast <DWORD *> ( shaderBlob->GetBufferPointer () ), | |
shaderBlob->GetBufferSize (), nullptr, | |
reinterpret_cast <ID3D11PixelShader **> | |
(&shader) | |
); | |
} | |
else | |
{ | |
#pragma warning (push) | |
#pragma warning (disable: 4130) // No @#$% sherlock | |
SK_ReleaseAssert ("WTF?!" == nullptr) | |
#pragma warning (pop) | |
} | |
return | |
SUCCEEDED (hrCompile); | |
#endif | |
} | |
bool compileShaderFile ( const wchar_t* wszShaderFile, | |
const char* szEntryPoint, | |
const char* szShaderModel, | |
bool recompile = | |
false, | |
std::string& error_log = | |
_SpecialNowhere ) | |
{ | |
std::wstring wstr_file = | |
wszShaderFile; | |
SK_ConcealUserDir ( | |
wstr_file.data () | |
); | |
if ( GetFileAttributesW (wszShaderFile) == INVALID_FILE_ATTRIBUTES ) | |
{ | |
static | |
Concurrency::concurrent_unordered_set | |
<std::wstring> warned_shaders; | |
if (! warned_shaders.count (wszShaderFile) ) | |
{ warned_shaders.insert (wszShaderFile); | |
SK_LOG0 ( ( L"Shader Compile Failed: File '%ws' Is Not Valid!", | |
wstr_file.c_str () | |
), L"D3DCompile" ); | |
} | |
return false; | |
} | |
FILE* fShader = | |
_wfsopen ( wszShaderFile, L"rtS", | |
_SH_DENYNO ); | |
if (fShader != nullptr) | |
{ | |
uint64_t size = | |
SK_File_GetSize (wszShaderFile); | |
auto data = | |
std::make_unique <char> (static_cast <size_t> (size) + 32); | |
memset ( data.get (), 0, | |
gsl::narrow_cast <size_t> (size) + 32 ); | |
fread ( data.get (), 1, | |
gsl::narrow_cast <size_t> (size) + 2, | |
fShader ); | |
fclose (fShader); | |
const bool result = | |
compileShaderString ( | |
data.get (), | |
wstr_file.c_str (), szEntryPoint, szShaderModel, | |
recompile, error_log | |
); | |
return result; | |
} | |
SK_LOG0 ( (L"Cannot Compile Shader Because of Filesystem Issues"), | |
L"D3DCompile" ); | |
return false; | |
} | |
void releaseResources (void) | |
{ | |
if (shader != nullptr) { shader->Release (); shader = nullptr; } | |
if (shaderBlob != nullptr) { shaderBlob->Release (); shaderBlob = nullptr; } | |
} | |
}; | |
using namespace SK::D3D11On12; | |
namespace SK::D3D11On12::ShaderTask { | |
class SDR_to_HDR | |
{ | |
public: | |
SDR_to_HDR ( const std::wstring& _name, | |
uint32_t vs_crc32c, | |
uint32_t ps_crc32c ) | |
{ | |
name = _name; | |
*(&vertexOverride._Myfirst._Val) = vs_crc32c; | |
*(&pixelOverride._Myfirst._Val) = ps_crc32c; | |
} | |
std::wstring name; | |
protected: | |
std::tuple < | |
uint32_t, VertexShader, | |
ID3D10Blob*> vertexOverride; | |
std::tuple < | |
uint32_t, PixelShader, | |
ID3D10Blob*> pixelOverride; | |
private: | |
SK_ComPtr <ID3D11VertexShader> pVS; | |
SK_ComPtr <ID3D11PixelShader> pPS; | |
}; | |
}; | |
#define STEAM_OVERLAY_VS_CRC32C 0xf48cf597 | |
#define STEAM_OVERLAY_PS_CRC32C 0xdeadbeef | |
#define RTSS_OVERLAY_VS_CRC32C 0xdeadbeef | |
#define RTSS_OVERLAY_PS_CRC32C 0xdeadbeef | |
#define DISCORD_OVERLAY_VS_CRC32C 0xdeadbeef | |
#define DISCORD_OVERLAY_PS_CRC32C 0xdeadbeef | |
#define UPLAY_OVERLAY_VS_CRC32C 0xdeadbeef | |
#define UPLAY_OVERLAY_PS_CRC32C 0xdeadbeef | |
SK::D3D11On12::ShaderTask::SDR_to_HDR | |
_SK_Steam_to_HDR_D3D12 ( L"Steam Overlay HDR Fix", | |
STEAM_OVERLAY_VS_CRC32C, | |
STEAM_OVERLAY_PS_CRC32C ); | |
SK::D3D11On12::ShaderTask::SDR_to_HDR | |
_SK_RTSS_to_HDR_D3D12 ( L"RTSS Overlay HDR Fix", | |
RTSS_OVERLAY_VS_CRC32C, | |
RTSS_OVERLAY_PS_CRC32C ); | |
SK::D3D11On12::ShaderTask::SDR_to_HDR | |
_SK_DISCORD_to_HDR_D3D12 ( L"Discord Overlay HDR Fix", | |
DISCORD_OVERLAY_VS_CRC32C, | |
DISCORD_OVERLAY_PS_CRC32C ); | |
SK::D3D11On12::ShaderTask::SDR_to_HDR | |
_SK_UPLAY_to_HDR_D3D12 ( L"uPlay Overlay HDR Fix", | |
UPLAY_OVERLAY_VS_CRC32C, | |
UPLAY_OVERLAY_PS_CRC32C ); | |
#if 0 | |
HRESULT compileShader (const char* szShaderSource) | |
{ | |
ShaderBase <ID3D11PixelShader> PixelShader_HDR10toscRGB; | |
static ShaderBase <ID3D11VertexShader> VertexShaderHDR_Util; | |
SK_RunOnce ( compiled = | |
PixelShader_HDR10toscRGB.compileShaderString ( | |
"#pragma warning ( disable : 3571 ) \n\ | |
struct PS_INPUT \n\ | |
{ \n\ | |
float4 pos : SV_POSITION; \n\ | |
float4 color : COLOR0; \n\ | |
float2 uv : TEXCOORD0; \n\ | |
float2 coverage : TEXCOORD1; \n\ | |
}; \n\ | |
\n\ | |
sampler sampler0 : register (s0); \n\ | |
Texture2D texHDR10 : register (t0); \n\ | |
\n\ | |
static const double3x3 from2020to709 = { \n\ | |
1.660496, -0.587656, -0.072840, \n\ | |
-0.124546, 1.132895, 0.008348, \n\ | |
-0.018154, -0.100597, 1.118751 \n\ | |
}; \n\ | |
\n\ | |
double3 RemoveREC2084Curve (double3 N) \n\ | |
{ \n\ | |
double m1 = 2610.0 / 4096.0 / 4; \n\ | |
double m2 = 2523.0 / 4096.0 * 128; \n\ | |
double c1 = 3424.0 / 4096.0; \n\ | |
double c2 = 2413.0 / 4096.0 * 32; \n\ | |
double c3 = 2392.0 / 4096.0 * 32; \n\ | |
double3 Np = pow (N, 1 / m2); \n\ | |
\n\ | |
return \n\ | |
pow (max (Np - c1, 0) / (c2 - c3 * Np), 1 / m1); \n\ | |
} \n\ | |
\n\ | |
float4 main ( PS_INPUT input ) : SV_TARGET \n\ | |
{ \n\ | |
double4 hdr10_color = \n\ | |
texHDR10.Sample (sampler0, input.uv); \n\ | |
\n\ | |
// HDR10 (normalized) is 125x brighter than scRGB \n\ | |
hdr10_color.rgb = \n\ | |
125.0 * \n\ | |
mul ( from2020to709, \n\ | |
RemoveREC2084Curve ( hdr10_color.rgb ) \n\ | |
); \n\ | |
\n\ | |
return \n\ | |
float4 (hdr10_color.rgb, 1.0); \n\ | |
}", L"HDR10->scRGB Color Transform", "main", "ps_5_0", true ) | |
#endif | |
std::string | |
__SK_MakeSteamPS ( bool hdr10, | |
bool scRGB, | |
float max_luma ) | |
{ | |
std::string out = | |
"\n" | |
"#pragma warning ( disable : 3571 ) \n" | |
"struct PS_INPUT \n" | |
"{ \n" | |
" float4 pos : SV_POSITION; \n" | |
" float4 col : COLOR; \n" | |
" float2 uv : TEXCOORD0; \n" | |
"}; \n" | |
" \n" | |
"sampler PS_QUAD_Sampler : register (s0); \n" | |
"Texture2D PS_QUAD_Texture2D : register (t0); \n" | |
" \n" | |
"float3 RemoveSRGBCurve (float3 x) \n" | |
"{ \n" | |
" x = \n" | |
" max ( 0.0, isfinite (x) ? x : 0.0 ); \n" | |
" \n" | |
" return ( x < 0.04045f ) ? \n" | |
" (x / 12.92f) : \n" | |
" pow ( (x + 0.055f) / 1.055f, 2.4f ); \n" | |
"} \n" | |
" \n"; | |
if (hdr10) | |
{ out += | |
"float3 ApplyREC2084Curve (float3 L, float maxLuminance)\n" | |
"{ \n" | |
" float m1 = 2610.0 / 4096.0 / 4; \n" | |
" float m2 = 2523.0 / 4096.0 * 128; \n" | |
" float c1 = 3424.0 / 4096.0; \n" | |
" float c2 = 2413.0 / 4096.0 * 32; \n" | |
" float c3 = 2392.0 / 4096.0 * 32; \n" | |
" \n" | |
" float maxLuminanceScale = maxLuminance / 10000.0f; \n" | |
" L *= maxLuminanceScale; \n" | |
" \n" | |
" float3 Lp = pow (L, m1); \n" | |
" \n" | |
" return pow ((c1 + c2 * Lp) / (1 + c3 * Lp), m2); \n" | |
"} \n" | |
" \n" | |
"float3 REC709toREC2020 (float3 RGB709) \n" | |
"{ \n" | |
" static const float3x3 ConvMat = \n" | |
" { \n" | |
" 0.627402, 0.329292, 0.043306, \n" | |
" 0.069095, 0.919544, 0.011360, \n" | |
" 0.016394, 0.088028, 0.895578 \n" | |
" }; \n" | |
" return mul (ConvMat, RGB709); \n" | |
"} \n" | |
" \n"; | |
} | |
out += | |
" \n" | |
"float4 main (PS_INPUT input) : SV_Target \n" | |
"{ \n" | |
" float4 out_col = \n" | |
" PS_QUAD_Texture2D.Sample (PS_QUAD_Sampler, input.uv);\n" | |
" \n" | |
" out_col = \n" | |
" float4 ( \n" | |
" RemoveSRGBCurve ( input.col.rgb * out_col.rgb ), \n" | |
" input.col.a * out_col.a \n" | |
" ); \n" | |
" \n"; | |
if (hdr10) | |
{ out += | |
" \n" | |
" out_col.rgb = \n" | |
" ApplyREC2084Curve ( \n" | |
" REC709toREC2020 ( out_col.rgb ), \n"; | |
out += std::to_string (max_luma); | |
out += "\n"; | |
out += | |
" ); \n" | |
" \n"; | |
} | |
if (scRGB) | |
{ | |
out += " out_col *= float4 (" + | |
std::to_string (max_luma) + ", " + | |
std::to_string (max_luma) + ", " + | |
std::to_string (max_luma) + ", 1.0); \n"; | |
" \n"; | |
} | |
out += | |
" return \n" | |
" float4 ( out_col.rgb, \n" | |
" saturate (out_col.a) \n" | |
" ); \n" | |
"} \n"; | |
return out; | |
} | |
ID3D10Blob* | |
__SK_MakeSteamPS_Bytecode ( bool hdr10, | |
bool scRGB, | |
float max_luma ) | |
{ | |
static ShaderBase <ID3D11PixelShader> steam_hdr; | |
steam_hdr.releaseResources (); | |
std::string steam_ps = | |
__SK_MakeSteamPS (hdr10, scRGB, max_luma); | |
steam_hdr.assembleShaderString ( | |
steam_ps.c_str (), | |
L"Steam HDR PS", | |
"main", "ps_5_0", true | |
); | |
return steam_hdr.shaderBlob; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment