-
Notifications
You must be signed in to change notification settings - Fork 165
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is the plug-in built in to Special K, included here for brevity.
- Loading branch information
Showing
1 changed file
with
238 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,238 @@ | ||
#define _CRT_SECURE_NO_WARNINGS | ||
|
||
#include <SpecialK/dxgi_backend.h> | ||
#include <SpecialK/config.h> | ||
#include <SpecialK/command.h> | ||
#include <SpecialK/ini.h> | ||
#include <SpecialK/parameter.h> | ||
#include <SpecialK/utility.h> | ||
#include <SpecialK/log.h> | ||
|
||
#include <SpecialK/hooks.h> | ||
#include <SpecialK/core.h> | ||
#include <process.h> | ||
|
||
#include <imgui/imgui.h> | ||
#include <imgui/backends/imgui_d3d11.h> | ||
|
||
#include <atlbase.h> | ||
|
||
|
||
sk::ParameterFactory far_factory; | ||
iSK_INI* far_prefs = nullptr; | ||
sk::ParameterInt* far_gi_workgroups = nullptr; | ||
|
||
|
||
// (Presumable) Size of compute shader workgroup | ||
int __FAR_GlobalIllumWorkGroupSize = 128; | ||
|
||
extern void | ||
__stdcall | ||
SK_SetPluginName (std::wstring name); | ||
|
||
#define FAR_VERSION_NUM L"0.1.0" | ||
#define FAR_VERSION_STR L"FAR v " FAR_VERSION_NUM | ||
|
||
|
||
typedef HRESULT (WINAPI *D3D11Dev_CreateBuffer_pfn)( | ||
_In_ ID3D11Device *This, | ||
_In_ const D3D11_BUFFER_DESC *pDesc, | ||
_In_opt_ const D3D11_SUBRESOURCE_DATA *pInitialData, | ||
_Out_opt_ ID3D11Buffer **ppBuffer | ||
); | ||
typedef HRESULT (WINAPI *D3D11Dev_CreateShaderResourceView_pfn)( | ||
_In_ ID3D11Device *This, | ||
_In_ ID3D11Resource *pResource, | ||
_In_opt_ const D3D11_SHADER_RESOURCE_VIEW_DESC *pDesc, | ||
_Out_opt_ ID3D11ShaderResourceView **ppSRView | ||
); | ||
|
||
static D3D11Dev_CreateBuffer_pfn D3D11Dev_CreateBuffer_Original; | ||
static D3D11Dev_CreateShaderResourceView_pfn D3D11Dev_CreateShaderResourceView_Original; | ||
|
||
extern | ||
HRESULT | ||
WINAPI | ||
D3D11Dev_CreateBuffer_Override ( | ||
_In_ ID3D11Device *This, | ||
_In_ const D3D11_BUFFER_DESC *pDesc, | ||
_In_opt_ const D3D11_SUBRESOURCE_DATA *pInitialData, | ||
_Out_opt_ ID3D11Buffer **ppBuffer ); | ||
|
||
extern | ||
HRESULT | ||
WINAPI | ||
D3D11Dev_CreateShaderResourceView_Override ( | ||
_In_ ID3D11Device *This, | ||
_In_ ID3D11Resource *pResource, | ||
_In_opt_ const D3D11_SHADER_RESOURCE_VIEW_DESC *pDesc, | ||
_Out_opt_ ID3D11ShaderResourceView **ppSRView ); | ||
|
||
|
||
unsigned int | ||
__stdcall | ||
SK_FAR_CheckVersionThread (LPVOID user) | ||
{ | ||
UNREFERENCED_PARAMETER (user); | ||
|
||
extern bool | ||
__stdcall | ||
SK_FetchVersionInfo (const wchar_t* wszProduct); | ||
|
||
if (SK_FetchVersionInfo (L"FAR")) { | ||
extern HRESULT | ||
__stdcall | ||
SK_UpdateSoftware (const wchar_t* wszProduct); | ||
|
||
SK_UpdateSoftware (L"FAR"); | ||
} | ||
|
||
CloseHandle (GetCurrentThread ()); | ||
|
||
return 0; | ||
} | ||
|
||
HRESULT | ||
WINAPI | ||
SK_FAR_CreateBuffer ( | ||
_In_ ID3D11Device *This, | ||
_In_ const D3D11_BUFFER_DESC *pDesc, | ||
_In_opt_ const D3D11_SUBRESOURCE_DATA *pInitialData, | ||
_Out_opt_ ID3D11Buffer **ppBuffer ) | ||
{ | ||
if ( pDesc != nullptr && pDesc->StructureByteStride == 96 && | ||
pDesc->ByteWidth == 96 * 128 ) | ||
{ | ||
D3D11_BUFFER_DESC new_desc = *pDesc; | ||
|
||
new_desc.ByteWidth = 96 * __FAR_GlobalIllumWorkGroupSize; | ||
|
||
return D3D11Dev_CreateBuffer_Original (This, &new_desc, pInitialData, ppBuffer); | ||
} | ||
|
||
return D3D11Dev_CreateBuffer_Original (This, pDesc, pInitialData, ppBuffer); | ||
} | ||
|
||
HRESULT | ||
WINAPI | ||
SK_FAR_CreateShaderResourceView ( | ||
_In_ ID3D11Device *This, | ||
_In_ ID3D11Resource *pResource, | ||
_In_opt_ const D3D11_SHADER_RESOURCE_VIEW_DESC *pDesc, | ||
_Out_opt_ ID3D11ShaderResourceView **ppSRView ) | ||
{ | ||
if ( pDesc != nullptr && pDesc->ViewDimension == D3D_SRV_DIMENSION_BUFFEREX && | ||
pDesc->BufferEx.NumElements == 128 ) | ||
{ | ||
CComPtr <ID3D11Buffer> pBuf; | ||
|
||
if ( SUCCEEDED ( | ||
pResource->QueryInterface (__uuidof (ID3D11Buffer), (void **)&pBuf) | ||
) | ||
) | ||
{ | ||
D3D11_SHADER_RESOURCE_VIEW_DESC new_desc = *pDesc; | ||
D3D11_BUFFER_DESC buf_desc; | ||
|
||
pBuf->GetDesc (&buf_desc); | ||
|
||
if (buf_desc.ByteWidth == 96 * __FAR_GlobalIllumWorkGroupSize) | ||
new_desc.BufferEx.NumElements = __FAR_GlobalIllumWorkGroupSize; | ||
|
||
return D3D11Dev_CreateShaderResourceView_Original (This, pResource, &new_desc, ppSRView); | ||
} | ||
} | ||
|
||
return D3D11Dev_CreateShaderResourceView_Original (This, pResource, pDesc, ppSRView); | ||
} | ||
|
||
void | ||
SK_FAR_InitPlugin (void) | ||
{ | ||
if (! SK_IsInjected ()) | ||
_beginthreadex ( nullptr, | ||
0, | ||
SK_FAR_CheckVersionThread, | ||
nullptr, | ||
0x00, | ||
nullptr ); | ||
|
||
SK_SetPluginName (FAR_VERSION_STR); | ||
|
||
SK_CreateFuncHook ( L"ID3D11Device::CreateBuffer", | ||
D3D11Dev_CreateBuffer_Override, | ||
SK_FAR_CreateBuffer, | ||
(LPVOID *)&D3D11Dev_CreateBuffer_Original ); | ||
MH_QueueEnableHook (D3D11Dev_CreateBuffer_Override); | ||
|
||
SK_CreateFuncHook ( L"ID3D11Device::CreateShaderResourceView", | ||
D3D11Dev_CreateShaderResourceView_Override, | ||
SK_FAR_CreateShaderResourceView, | ||
(LPVOID *)&D3D11Dev_CreateShaderResourceView_Original ); | ||
MH_QueueEnableHook (D3D11Dev_CreateShaderResourceView_Override); | ||
|
||
MH_ApplyQueued (); | ||
|
||
|
||
if (far_prefs == nullptr) | ||
{ | ||
wchar_t far_prefs_file [MAX_PATH] = { L'\0' }; | ||
|
||
lstrcatW (far_prefs_file, SK_GetConfigPath ()); | ||
lstrcatW (far_prefs_file, L"FAR.ini"); | ||
|
||
far_prefs = new iSK_INI (far_prefs_file); | ||
far_prefs->parse (); | ||
|
||
far_gi_workgroups = | ||
static_cast <sk::ParameterInt *> | ||
(far_factory.create_parameter <int> (L"Global Illumination Compute Shader Workgroups")); | ||
|
||
far_gi_workgroups->register_to_ini ( far_prefs, | ||
L"FAR.Lighting", | ||
L"GlobalIlluminationWorkgroups" ); | ||
|
||
if ( far_prefs->get_section (L"FAR.Lighting").contains_key (L"GlobalIlluminationWorkgroups") ) | ||
__FAR_GlobalIllumWorkGroupSize = far_gi_workgroups->get_value (); | ||
|
||
far_gi_workgroups->set_value (__FAR_GlobalIllumWorkGroupSize); | ||
far_gi_workgroups->store (); | ||
|
||
far_prefs->write (far_prefs_file); | ||
|
||
|
||
SK_GetCommandProcessor ()->AddVariable ("FAR.GIWorkgroups", SK_CreateVar (SK_IVariable::Int, &__FAR_GlobalIllumWorkGroupSize)); | ||
} | ||
} | ||
|
||
// Not currently used | ||
bool | ||
WINAPI | ||
SK_FAR_ShutdownPlugin (const wchar_t* backend) | ||
{ | ||
UNREFERENCED_PARAMETER (backend); | ||
|
||
return true; | ||
} | ||
|
||
|
||
void | ||
__stdcall | ||
SK_FAR_ControlPanel (void) | ||
{ | ||
if (ImGui::CollapsingHeader("NieR: Automata")) | ||
{ | ||
if (ImGui::SliderInt ("Global Illumination Workgroup Size", &__FAR_GlobalIllumWorkGroupSize, 0, 128)) | ||
{ | ||
if (__FAR_GlobalIllumWorkGroupSize % 16 > 0) | ||
__FAR_GlobalIllumWorkGroupSize += 16 - (__FAR_GlobalIllumWorkGroupSize % 16); | ||
} | ||
} | ||
} | ||
|
||
bool | ||
__stdcall | ||
SK_FAR_IsPlugIn (void) | ||
{ | ||
return far_prefs != nullptr; | ||
} |