Skip to content

Commit

Permalink
R3/R4: create geometry shader using ShaderTypeTraits
Browse files Browse the repository at this point in the history
This removes code dublication
New command line key -lack_of_shaders
If it is enabled, engine won't crash when some shaders are missing
  • Loading branch information
Xottab-DUTY committed May 27, 2018
1 parent b1acf0b commit 8855679
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 156 deletions.
20 changes: 12 additions & 8 deletions src/Layers/xrRender/ResourceManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class ECORE_API CResourceManager
using map_RT = xr_map<const char*, CRT*, str_pred>;
// DX10 cut DEFINE_MAP_PRED(const char*,CRTC*, map_RTC, map_RTCIt, str_pred);
using map_VS = xr_map<const char*, SVS*, str_pred>;

#if defined(USE_DX10) || defined(USE_DX11) || defined(USE_OGL)
using map_GS = xr_map<const char*, SGS*, str_pred>;
#endif // USE_DX10
Expand All @@ -59,9 +60,17 @@ class ECORE_API CResourceManager
// DX10 cut map_RTC m_rtargets_c;
map_VS m_vs;
map_PS m_ps;

#if defined(USE_DX10) || defined(USE_DX11) || defined(USE_OGL)
map_GS m_gs;
#endif // USE_DX10
#endif

#if defined(USE_DX11)
map_DS m_ds;
map_HS m_hs;
map_CS m_cs;
#endif

map_TD m_td;

xr_vector<SState*> v_states;
Expand Down Expand Up @@ -239,11 +248,7 @@ class ECORE_API CResourceManager
void Dump(bool bBrief);

private:
#ifdef USE_DX11
map_DS m_ds;
map_HS m_hs;
map_CS m_cs;

#if defined(USE_DX10) || defined(USE_DX11)
template <typename T>
T& GetShaderMap();

Expand All @@ -252,8 +257,7 @@ class ECORE_API CResourceManager

template <typename T>
void DestroyShader(const T* sh);

#endif // USE_DX10
#endif
};

#endif // ResourceManagerH
82 changes: 73 additions & 9 deletions src/Layers/xrRender/ShaderResourceTraits.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,55 @@
#pragma once

#ifdef USE_DX11
#if defined(USE_DX10) || defined(USE_DX11)

#include "ResourceManager.h"

template <typename T>
struct ShaderTypeTraits;

#if defined(USE_DX10) || defined(USE_DX11)
template <>
struct ShaderTypeTraits<SGS>
{
typedef CResourceManager::map_GS MapType;
typedef ID3DGeometryShader DXIface;

static inline const char* GetShaderExt() { return ".gs"; }
static inline const char* GetCompilationTarget()
{
#ifdef USE_DX10
if (HW.pDevice1 == 0)
return D3D10GetGeometryShaderProfile(HW.pDevice);
else
return "gs_4_1";
#endif
#ifdef USE_DX11
if (HW.FeatureLevel == D3D_FEATURE_LEVEL_10_0)
return "gs_4_0";
else if (HW.FeatureLevel == D3D_FEATURE_LEVEL_10_1)
return "gs_4_1";
else if (HW.FeatureLevel == D3D_FEATURE_LEVEL_11_0)
return "gs_5_0";
#endif
NODEFAULT;
return "gs_4_0";
}
static inline DXIface* CreateHWShader(DWORD const* buffer, size_t size)
{
DXIface* gs = 0;
#ifdef USE_DX11
R_CHK(HW.pDevice->CreateGeometryShader(buffer, size, 0, &gs));
#else
R_CHK(HW.pDevice->CreateGeometryShader(buffer, size, &gs));
#endif
return gs;
}

static inline u32 GetShaderDest() { return RC_dest_geometry; }
};
#endif

#ifdef USE_DX11
template <>
struct ShaderTypeTraits<SHS>
{
Expand Down Expand Up @@ -60,7 +103,17 @@ struct ShaderTypeTraits<SCS>

static inline u32 GetShaderDest() { return RC_dest_compute; }
};
#endif

#if defined(USE_DX10) || defined(USE_DX11)
template <>
inline CResourceManager::map_GS& CResourceManager::GetShaderMap()
{
return m_gs;
}
#endif

#if defined(USE_DX11)
template <>
inline CResourceManager::map_DS& CResourceManager::GetShaderMap()
{
Expand All @@ -78,16 +131,17 @@ inline CResourceManager::map_CS& CResourceManager::GetShaderMap()
{
return m_cs;
}
#endif

template <typename T>
inline T* CResourceManager::CreateShader(const char* name)
{
ShaderTypeTraits<T>::MapType& sh_map = GetShaderMap<ShaderTypeTraits<T>::MapType>();
LPSTR N = LPSTR(name);
ShaderTypeTraits<T>::MapType::iterator I = sh_map.find(N);
auto iterator = sh_map.find(N);

if (I != sh_map.end())
return I->second;
if (iterator != sh_map.end())
return iterator->second;
else
{
T* sh = new T();
Expand All @@ -100,6 +154,7 @@ inline T* CResourceManager::CreateShader(const char* name)
return sh;
}

// Remove ( and everything after it
string_path shName;
const char* pchr = strchr(name, '(');
ptrdiff_t strSize = pchr ? pchr - name : xr_strlen(name);
Expand All @@ -114,6 +169,15 @@ inline T* CResourceManager::CreateShader(const char* name)

// duplicate and zero-terminate
IReader* file = FS.r_open(cname);
if (!file && strstr(Core.Params, "-lack_of_shaders"))
{
string1024 tmp;
xr_sprintf(tmp, "CreateShader: %s is missing. Replacing it with stub_default%s", cname, ShaderTypeTraits<T>::GetShaderExt());
Msg(tmp);
strconcat(sizeof(cname), cname, GEnv.Render->getShaderPath(), "stub_default", ShaderTypeTraits<T>::GetShaderExt());
FS.update_path(cname, "$game_shaders$", cname);
file = FS.r_open(cname);
}
R_ASSERT2(file, cname);

// Select target
Expand All @@ -137,17 +201,17 @@ inline T* CResourceManager::CreateShader(const char* name)
template <typename T>
inline void CResourceManager::DestroyShader(const T* sh)
{
ShaderTypeTraits<T>::MapType& sh_map = GetShaderMap<ShaderTypeTraits<T>::MapType>();

if (0 == (sh->dwFlags & xr_resource_flagged::RF_REGISTERED))
return;

ShaderTypeTraits<T>::MapType& sh_map = GetShaderMap<ShaderTypeTraits<T>::MapType>();

LPSTR N = LPSTR(*sh->cName);
typename ShaderTypeTraits<T>::MapType::iterator I = sh_map.find(N);
auto iterator = sh_map.find(N);

if (I != sh_map.end())
if (iterator != sh_map.end())
{
sh_map.erase(I);
sh_map.erase(iterator);
return;
}
Msg("! ERROR: Failed to find compiled geometry shader '%s'", *sh->cName);
Expand Down
72 changes: 3 additions & 69 deletions src/Layers/xrRenderDX10/dx10ResourceManager_Resources.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
#include "Layers/xrRenderDX10/dx10ConstantBuffer.h"
#include "Layers/xrRender/ShaderResourceTraits.h"

SGS* CResourceManager::_CreateGS(LPCSTR Name) { return CreateShader<SGS>(Name); }
void CResourceManager::_DeleteGS(const SGS* GS) { DestroyShader(GS); }

#ifdef USE_DX11
SHS* CResourceManager::_CreateHS(LPCSTR Name) { return CreateShader<SHS>(Name); }
void CResourceManager::_DeleteHS(const SHS* HS) { DestroyShader(HS); }
Expand Down Expand Up @@ -356,75 +359,6 @@ void CResourceManager::_DeletePS(const SPS* ps)
Msg("! ERROR: Failed to find compiled pixel-shader '%s'", *ps->cName);
}

//--------------------------------------------------------------------------------------------------------------
SGS* CResourceManager::_CreateGS(LPCSTR name)
{
LPSTR N = LPSTR(name);
map_GS::iterator I = m_gs.find(N);
if (I != m_gs.end())
return I->second;
else
{
SGS* _gs = new SGS();
_gs->dwFlags |= xr_resource_flagged::RF_REGISTERED;
m_gs.insert(std::make_pair(_gs->set_name(name), _gs));
if (0 == xr_stricmp(name, "null"))
{
_gs->sh = NULL;
return _gs;
}

// Open file
string_path cname;
strconcat(sizeof(cname), cname, GEnv.Render->getShaderPath(), name, ".gs");
FS.update_path(cname, "$game_shaders$", cname);

// duplicate and zero-terminate
IReader* file = FS.r_open(cname);
// TODO: DX10: HACK: Implement all shaders. Remove this for PS
if (!file)
{
string1024 tmp;
// TODO: HACK: Test failure
// Memory.mem_compact();
xr_sprintf(tmp, "DX10: %s is missing. Replace with stub_default.gs", cname);
Msg(tmp);
strconcat(sizeof(cname), cname, GEnv.Render->getShaderPath(), "stub_default", ".gs");
FS.update_path(cname, "$game_shaders$", cname);
file = FS.r_open(cname);
}
R_ASSERT2(file, cname);

// Select target
LPCSTR c_target = "gs_4_0";
LPCSTR c_entry = "main";

HRESULT const _hr = GEnv.Render->shader_compile(name, (DWORD const*)file->pointer(), file->length(),
c_entry, c_target, D3D10_SHADER_PACK_MATRIX_ROW_MAJOR, (void*&)_gs);

VERIFY(SUCCEEDED(_hr));

FS.r_close(file);

CHECK_OR_EXIT(!FAILED(_hr), "Your video card doesn't meet game requirements.\n\nTry to lower game settings.");

return _gs;
}
}
void CResourceManager::_DeleteGS(const SGS* gs)
{
if (0 == (gs->dwFlags & xr_resource_flagged::RF_REGISTERED))
return;
LPSTR N = LPSTR(*gs->cName);
map_GS::iterator I = m_gs.find(N);
if (I != m_gs.end())
{
m_gs.erase(I);
return;
}
Msg("! ERROR: Failed to find compiled geometry shader '%s'", *gs->cName);
}

//--------------------------------------------------------------------------------------------------------------
static BOOL dcl_equal(D3DVERTEXELEMENT9* a, D3DVERTEXELEMENT9* b)
{
Expand Down
69 changes: 34 additions & 35 deletions src/Layers/xrRenderPC_R3/r3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "Layers/xrRender/dxWallMarkArray.h"
#include "Layers/xrRender/dxUIShader.h"
#include "Layers/xrRenderDX10/3DFluid/dx103DFluidManager.h"
#include "Layers/xrRender/ShaderResourceTraits.h"
#include "D3DX10Core.h"

CRender RImplementation;
Expand Down Expand Up @@ -758,8 +759,40 @@ void CRender::DumpStatistics(IGameFont& font, IPerformanceAlert* alert)
Sectors_xrc.DumpStatistics(font, alert);
}

template <typename T>
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<T>::CreateHWShader(buffer, buffer_size);

ID3DShaderReflection* pReflection = 0;

#ifdef USE_DX11
HRESULT const _hr = D3DReflect(buffer, buffer_size, IID_ID3DShaderReflection, (void**)&pReflection);
#else
HRESULT const _hr = D3D10ReflectShader(buffer, buffer_size, &pReflection);
#endif

if (SUCCEEDED(_hr) && pReflection)
{
// Parse constant table data
result->constants.parse(pReflection, ShaderTypeTraits<T>::GetShaderDest());

_RELEASE(pReflection);
}
else
{
Msg("! D3DReflectShader %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)
{
// XXX: what's going on with casts here???
HRESULT _result = E_FAIL;
if (pTarget[0] == 'p')
{
Expand Down Expand Up @@ -852,41 +885,7 @@ static HRESULT create_shader(LPCSTR const pTarget, DWORD const* buffer, u32 cons
}
else if (pTarget[0] == 'g')
{
SGS* sgs_result = (SGS*)result;
#ifdef USE_DX11
_result = HW.pDevice->CreateGeometryShader(buffer, buffer_size, 0, &sgs_result->sh);
#else // #ifdef USE_DX11
_result = HW.pDevice->CreateGeometryShader(buffer, buffer_size, &sgs_result->sh);
#endif // #ifdef USE_DX11
if (!SUCCEEDED(_result))
{
Log("! GS: ", file_name);
Msg("! CreateGeometryShaderhr == 0x%08x", _result);
return E_FAIL;
}

ID3DShaderReflection* pReflection = 0;

#ifdef USE_DX11
_result = D3DReflect(buffer, buffer_size, IID_ID3DShaderReflection, (void**)&pReflection);
#else
_result = D3D10ReflectShader(buffer, buffer_size, &pReflection);
#endif

// Parse constant, texture, sampler binding
// Store input signature blob
if (SUCCEEDED(_result) && pReflection)
{
// Let constant table parse it's data
sgs_result->constants.parse(pReflection, RC_dest_geometry);

_RELEASE(pReflection);
}
else
{
Log("! PS: ", file_name);
Msg("! D3DReflectShader hr == 0x%08x", _result);
}
_result = create_shader(pTarget, buffer, buffer_size, file_name, (SGS*&)result, disasm);
}
else
{
Expand Down
Loading

0 comments on commit 8855679

Please sign in to comment.