diff --git a/src/Layers/xrRender/ResourceManager.h b/src/Layers/xrRender/ResourceManager.h index fff58509fc3..f84eec23bbc 100644 --- a/src/Layers/xrRender/ResourceManager.h +++ b/src/Layers/xrRender/ResourceManager.h @@ -251,7 +251,6 @@ class ECORE_API CResourceManager void Dump(bool bBrief); private: -#if defined(USE_DX10) || defined(USE_DX11) template T& GetShaderMap(); @@ -260,7 +259,6 @@ class ECORE_API CResourceManager template void DestroyShader(const T* sh); -#endif }; #endif // ResourceManagerH diff --git a/src/Layers/xrRender/ResourceManager_Resources.cpp b/src/Layers/xrRender/ResourceManager_Resources.cpp index 73c28f8afbe..08526158867 100644 --- a/src/Layers/xrRender/ResourceManager_Resources.cpp +++ b/src/Layers/xrRender/ResourceManager_Resources.cpp @@ -14,6 +14,7 @@ #include "tss.h" #include "blenders/blender.h" #include "blenders/blender_recorder.h" +#include "ShaderResourceTraits.h" void fix_texture_name(LPSTR fn); @@ -252,98 +253,8 @@ void CResourceManager::_DeleteVS(const SVS* vs) Msg("! ERROR: Failed to find compiled vertex-shader '%s'", *vs->cName); } -#ifndef _EDITOR -//-------------------------------------------------------------------------------------------------------------- -SPS* CResourceManager::_CreatePS(LPCSTR name) -{ - LPSTR N = LPSTR(name); - map_PS::iterator I = m_ps.find(N); - if (I != m_ps.end()) - return I->second; - else - { - SPS* _ps = new SPS(); - _ps->dwFlags |= xr_resource_flagged::RF_REGISTERED; - m_ps.insert(std::make_pair(_ps->set_name(name), _ps)); - if (0 == xr_stricmp(name, "null")) - { - _ps->sh = nullptr; - return _ps; - } - - // Open file - string_path cname; - LPCSTR shader_path = GEnv.Render->getShaderPath(); - strconcat(sizeof(cname), cname, shader_path, name, ".ps"); - FS.update_path(cname, "$game_shaders$", cname); - - // duplicate and zero-terminate - IReader* file = FS.r_open(cname); - R_ASSERT2(file, cname); - u32 const size = file->length(); - char* const data = (LPSTR)_alloca(size + 1); - CopyMemory(data, file->pointer(), size); - data[size] = 0; - FS.r_close(file); - - // Select target - LPCSTR c_target = "ps_2_0"; - LPCSTR c_entry = "main"; - if (strstr(data, "main_ps_1_1")) - { - c_target = "ps_1_1"; - c_entry = "main_ps_1_1"; - } - if (strstr(data, "main_ps_1_2")) - { - c_target = "ps_1_2"; - c_entry = "main_ps_1_2"; - } - if (strstr(data, "main_ps_1_3")) - { - c_target = "ps_1_3"; - c_entry = "main_ps_1_3"; - } - if (strstr(data, "main_ps_1_4")) - { - c_target = "ps_1_4"; - c_entry = "main_ps_1_4"; - } - if (strstr(data, "main_ps_2_0")) - { - c_target = "ps_2_0"; - c_entry = "main_ps_2_0"; - } - - Msg("compiling shader %s", name); - HRESULT const _hr = GEnv.Render->shader_compile(name, (DWORD const*)data, size, c_entry, c_target, - D3DXSHADER_DEBUG | D3DXSHADER_PACKMATRIX_ROWMAJOR, (void*&)_ps); - - if (FAILED(_hr)) - { - FlushLog(); - } - - CHECK_OR_EXIT(!FAILED(_hr), "Your video card doesn't meet game requirements.\n\nTry to lower game settings."); - - return _ps; - } -} -#endif - -void CResourceManager::_DeletePS(const SPS* ps) -{ - if (0 == (ps->dwFlags & xr_resource_flagged::RF_REGISTERED)) - return; - LPSTR N = LPSTR(*ps->cName); - map_PS::iterator I = m_ps.find(N); - if (I != m_ps.end()) - { - m_ps.erase(I); - return; - } - Msg("! ERROR: Failed to find compiled pixel-shader '%s'", *ps->cName); -} +SPS* CResourceManager::_CreatePS(LPCSTR name) { return CreateShader(name, true); } +void CResourceManager::_DeletePS(const SPS* ps) { DestroyShader(ps); } R_constant_table* CResourceManager::_CreateConstantTable(R_constant_table& C) { diff --git a/src/Layers/xrRender/ShaderResourceTraits.h b/src/Layers/xrRender/ShaderResourceTraits.h index fd345b6eff5..e7e00b99d9d 100644 --- a/src/Layers/xrRender/ShaderResourceTraits.h +++ b/src/Layers/xrRender/ShaderResourceTraits.h @@ -1,13 +1,10 @@ #pragma once -#if defined(USE_DX10) || defined(USE_DX11) - #include "ResourceManager.h" template struct ShaderTypeTraits; -#if defined(USE_DX10) || defined(USE_DX11) template <> struct ShaderTypeTraits { @@ -57,7 +54,7 @@ struct ShaderTypeTraits #elif defined(USE_DX10) R_CHK(HW.pDevice->CreatePixelShader(buffer, size, &ps)); #else - R_CHK(HW.pDevice->CreatePixelShader(buffer, &ps); + R_CHK(HW.pDevice->CreatePixelShader(buffer, &ps)); #endif return ps; } @@ -65,6 +62,7 @@ struct ShaderTypeTraits static inline u32 GetShaderDest() { return RC_dest_pixel; } }; +#if defined(USE_DX10) || defined(USE_DX11) template <> struct ShaderTypeTraits { @@ -284,9 +282,17 @@ inline T* CResourceManager::CreateShader(const char* name, const bool searchForE if (searchForEntryAndTarget) ShaderTypeTraits::GetCompilationTarget(c_target, c_entry, data); +#ifdef USE_OGL + DWORD flags = NULL; +#elif defined(USE_DX10) || defined(USE_DX11) + DWORD flags = D3D10_SHADER_PACK_MATRIX_ROW_MAJOR; +#else + DWORD flags = D3DXSHADER_DEBUG | D3DXSHADER_PACKMATRIX_ROWMAJOR; +#endif + // Compile HRESULT const _hr = GEnv.Render->shader_compile(name, (DWORD const*)data, size, - c_entry, c_target, D3D10_SHADER_PACK_MATRIX_ROW_MAJOR, (void*&)sh); + c_entry, c_target, flags, (void*&)sh); VERIFY(SUCCEEDED(_hr)); @@ -312,7 +318,5 @@ inline void CResourceManager::DestroyShader(const T* sh) sh_map.erase(iterator); return; } - Msg("! ERROR: Failed to find compiled geometry shader '%s'", *sh->cName); + Msg("! ERROR: Failed to find compiled shader '%s'", sh->cName.c_str()); } - -#endif diff --git a/src/Layers/xrRenderPC_R1/FStaticRender.cpp b/src/Layers/xrRenderPC_R1/FStaticRender.cpp index 0807227b81d..149e3aea488 100644 --- a/src/Layers/xrRenderPC_R1/FStaticRender.cpp +++ b/src/Layers/xrRenderPC_R1/FStaticRender.cpp @@ -11,6 +11,7 @@ #include "Layers/xrRender/LightTrack.h" #include "Layers/xrRender/dxWallMarkArray.h" #include "Layers/xrRender/dxUIShader.h" +#include "Layers/xrRender/ShaderResourceTraits.h" CRender RImplementation; @@ -753,32 +754,38 @@ void CRender::DumpStatistics(IGameFont& font, IPerformanceAlert* alert) Sectors_xrc.DumpStatistics(font, alert); } +template +static HRESULT create_shader(LPCSTR const pTarget, DWORD const* buffer, u32 const buffer_size, LPCSTR const file_name, + T*& result, bool const disasm) +{ + // XXX: disasm it + + result->sh = ShaderTypeTraits::CreateHWShader(buffer, buffer_size); + + LPCVOID data = nullptr; + + HRESULT const _hr = D3DXFindShaderComment(buffer, MAKEFOURCC('C', 'T', 'A', 'B'), &data, nullptr); + + if (SUCCEEDED(_hr) && data) + { + // Parse constant table data + LPD3DXSHADER_CONSTANTTABLE pConstants = LPD3DXSHADER_CONSTANTTABLE(data); + result->constants.parse(pConstants, ShaderTypeTraits::GetShaderDest()); + } + else + { + Msg("! D3DXFindShaderComment %s hr == 0x%08x", file_name, _hr); + } + + return _hr; +} + static HRESULT create_shader(LPCSTR const pTarget, DWORD const* buffer, u32 const buffer_size, LPCSTR const file_name, void*& result, bool const disasm) { HRESULT _result = E_FAIL; if (pTarget[0] == 'p') { - SPS* sps_result = (SPS*)result; - _result = HW.pDevice->CreatePixelShader(buffer, &sps_result->sh); - if (!SUCCEEDED(_result)) - { - Log("! PS: ", file_name); - Msg("! CreatePixelShader hr == 0x%08x", _result); - return E_FAIL; - } - - LPCVOID data = nullptr; - _result = D3DXFindShaderComment(buffer, MAKEFOURCC('C', 'T', 'A', 'B'), &data, nullptr); - if (SUCCEEDED(_result) && data) - { - LPD3DXSHADER_CONSTANTTABLE pConstants = LPD3DXSHADER_CONSTANTTABLE(data); - sps_result->constants.parse(pConstants, 0x1); - } - else - { - Log("! PS: ", file_name); - Msg("! D3DXFindShaderComment hr == 0x%08x", _result); - } + _result = create_shader(pTarget, buffer, buffer_size, file_name, (SPS*&)result, disasm); } else if (pTarget[0] == 'v') { diff --git a/src/Layers/xrRenderPC_R2/r2.cpp b/src/Layers/xrRenderPC_R2/r2.cpp index 239e2222b59..0fe8ccb4281 100644 --- a/src/Layers/xrRenderPC_R2/r2.cpp +++ b/src/Layers/xrRenderPC_R2/r2.cpp @@ -11,6 +11,7 @@ #include "Layers/xrRender/LightTrack.h" #include "Layers/xrRender/dxWallMarkArray.h" #include "Layers/xrRender/dxUIShader.h" +#include "Layers/xrRender/ShaderResourceTraits.h" CRender RImplementation; @@ -628,32 +629,38 @@ void CRender::DumpStatistics(IGameFont& font, IPerformanceAlert* alert) Sectors_xrc.DumpStatistics(font, alert); } +template +static HRESULT create_shader(LPCSTR const pTarget, DWORD const* buffer, u32 const buffer_size, LPCSTR const file_name, + T*& result, bool const disasm) +{ + // XXX: disasm it + + result->sh = ShaderTypeTraits::CreateHWShader(buffer, buffer_size); + + LPCVOID data = nullptr; + + HRESULT const _hr = D3DXFindShaderComment(buffer, MAKEFOURCC('C', 'T', 'A', 'B'), &data, nullptr); + + if (SUCCEEDED(_hr) && data) + { + // Parse constant table data + LPD3DXSHADER_CONSTANTTABLE pConstants = LPD3DXSHADER_CONSTANTTABLE(data); + result->constants.parse(pConstants, ShaderTypeTraits::GetShaderDest()); + } + else + { + Msg("! D3DXFindShaderComment %s hr == 0x%08x", file_name, _hr); + } + + return _hr; +} + static HRESULT create_shader(LPCSTR const pTarget, DWORD const* buffer, u32 const buffer_size, LPCSTR const file_name, void*& result, bool const disasm) { HRESULT _result = E_FAIL; if (pTarget[0] == 'p') { - SPS* sps_result = (SPS*)result; - _result = HW.pDevice->CreatePixelShader(buffer, &sps_result->sh); - if (!SUCCEEDED(_result)) - { - Log("! PS: ", file_name); - Msg("! CreatePixelShader hr == 0x%08x", _result); - return E_FAIL; - } - - LPCVOID data = nullptr; - _result = D3DXFindShaderComment(buffer, MAKEFOURCC('C', 'T', 'A', 'B'), &data, nullptr); - if (SUCCEEDED(_result) && data) - { - LPD3DXSHADER_CONSTANTTABLE pConstants = LPD3DXSHADER_CONSTANTTABLE(data); - sps_result->constants.parse(pConstants, 0x1); - } - else - { - Log("! PS: ", file_name); - Msg("! D3DXFindShaderComment hr == 0x%08x", _result); - } + _result = create_shader(pTarget, buffer, buffer_size, file_name, (SPS*&)result, disasm); } else if (pTarget[0] == 'v') {