Skip to content

Commit 8855679

Browse files
committed
R3/R4: create geometry shader using ShaderTypeTraits
This removes code dublication New command line key -lack_of_shaders If it is enabled, engine won't crash when some shaders are missing
1 parent b1acf0b commit 8855679

File tree

5 files changed

+131
-156
lines changed

5 files changed

+131
-156
lines changed

src/Layers/xrRender/ResourceManager.h

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class ECORE_API CResourceManager
3737
using map_RT = xr_map<const char*, CRT*, str_pred>;
3838
// DX10 cut DEFINE_MAP_PRED(const char*,CRTC*, map_RTC, map_RTCIt, str_pred);
3939
using map_VS = xr_map<const char*, SVS*, str_pred>;
40+
4041
#if defined(USE_DX10) || defined(USE_DX11) || defined(USE_OGL)
4142
using map_GS = xr_map<const char*, SGS*, str_pred>;
4243
#endif // USE_DX10
@@ -59,9 +60,17 @@ class ECORE_API CResourceManager
5960
// DX10 cut map_RTC m_rtargets_c;
6061
map_VS m_vs;
6162
map_PS m_ps;
63+
6264
#if defined(USE_DX10) || defined(USE_DX11) || defined(USE_OGL)
6365
map_GS m_gs;
64-
#endif // USE_DX10
66+
#endif
67+
68+
#if defined(USE_DX11)
69+
map_DS m_ds;
70+
map_HS m_hs;
71+
map_CS m_cs;
72+
#endif
73+
6574
map_TD m_td;
6675

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

241250
private:
242-
#ifdef USE_DX11
243-
map_DS m_ds;
244-
map_HS m_hs;
245-
map_CS m_cs;
246-
251+
#if defined(USE_DX10) || defined(USE_DX11)
247252
template <typename T>
248253
T& GetShaderMap();
249254

@@ -252,8 +257,7 @@ class ECORE_API CResourceManager
252257

253258
template <typename T>
254259
void DestroyShader(const T* sh);
255-
256-
#endif // USE_DX10
260+
#endif
257261
};
258262

259263
#endif // ResourceManagerH

src/Layers/xrRender/ShaderResourceTraits.h

Lines changed: 73 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,55 @@
11
#pragma once
22

3-
#ifdef USE_DX11
3+
#if defined(USE_DX10) || defined(USE_DX11)
44

55
#include "ResourceManager.h"
66

77
template <typename T>
88
struct ShaderTypeTraits;
99

10+
#if defined(USE_DX10) || defined(USE_DX11)
11+
template <>
12+
struct ShaderTypeTraits<SGS>
13+
{
14+
typedef CResourceManager::map_GS MapType;
15+
typedef ID3DGeometryShader DXIface;
16+
17+
static inline const char* GetShaderExt() { return ".gs"; }
18+
static inline const char* GetCompilationTarget()
19+
{
20+
#ifdef USE_DX10
21+
if (HW.pDevice1 == 0)
22+
return D3D10GetGeometryShaderProfile(HW.pDevice);
23+
else
24+
return "gs_4_1";
25+
#endif
26+
#ifdef USE_DX11
27+
if (HW.FeatureLevel == D3D_FEATURE_LEVEL_10_0)
28+
return "gs_4_0";
29+
else if (HW.FeatureLevel == D3D_FEATURE_LEVEL_10_1)
30+
return "gs_4_1";
31+
else if (HW.FeatureLevel == D3D_FEATURE_LEVEL_11_0)
32+
return "gs_5_0";
33+
#endif
34+
NODEFAULT;
35+
return "gs_4_0";
36+
}
37+
static inline DXIface* CreateHWShader(DWORD const* buffer, size_t size)
38+
{
39+
DXIface* gs = 0;
40+
#ifdef USE_DX11
41+
R_CHK(HW.pDevice->CreateGeometryShader(buffer, size, 0, &gs));
42+
#else
43+
R_CHK(HW.pDevice->CreateGeometryShader(buffer, size, &gs));
44+
#endif
45+
return gs;
46+
}
47+
48+
static inline u32 GetShaderDest() { return RC_dest_geometry; }
49+
};
50+
#endif
51+
52+
#ifdef USE_DX11
1053
template <>
1154
struct ShaderTypeTraits<SHS>
1255
{
@@ -60,7 +103,17 @@ struct ShaderTypeTraits<SCS>
60103

61104
static inline u32 GetShaderDest() { return RC_dest_compute; }
62105
};
106+
#endif
107+
108+
#if defined(USE_DX10) || defined(USE_DX11)
109+
template <>
110+
inline CResourceManager::map_GS& CResourceManager::GetShaderMap()
111+
{
112+
return m_gs;
113+
}
114+
#endif
63115

116+
#if defined(USE_DX11)
64117
template <>
65118
inline CResourceManager::map_DS& CResourceManager::GetShaderMap()
66119
{
@@ -78,16 +131,17 @@ inline CResourceManager::map_CS& CResourceManager::GetShaderMap()
78131
{
79132
return m_cs;
80133
}
134+
#endif
81135

82136
template <typename T>
83137
inline T* CResourceManager::CreateShader(const char* name)
84138
{
85139
ShaderTypeTraits<T>::MapType& sh_map = GetShaderMap<ShaderTypeTraits<T>::MapType>();
86140
LPSTR N = LPSTR(name);
87-
ShaderTypeTraits<T>::MapType::iterator I = sh_map.find(N);
141+
auto iterator = sh_map.find(N);
88142

89-
if (I != sh_map.end())
90-
return I->second;
143+
if (iterator != sh_map.end())
144+
return iterator->second;
91145
else
92146
{
93147
T* sh = new T();
@@ -100,6 +154,7 @@ inline T* CResourceManager::CreateShader(const char* name)
100154
return sh;
101155
}
102156

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

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

119183
// Select target
@@ -137,17 +201,17 @@ inline T* CResourceManager::CreateShader(const char* name)
137201
template <typename T>
138202
inline void CResourceManager::DestroyShader(const T* sh)
139203
{
140-
ShaderTypeTraits<T>::MapType& sh_map = GetShaderMap<ShaderTypeTraits<T>::MapType>();
141-
142204
if (0 == (sh->dwFlags & xr_resource_flagged::RF_REGISTERED))
143205
return;
144206

207+
ShaderTypeTraits<T>::MapType& sh_map = GetShaderMap<ShaderTypeTraits<T>::MapType>();
208+
145209
LPSTR N = LPSTR(*sh->cName);
146-
typename ShaderTypeTraits<T>::MapType::iterator I = sh_map.find(N);
210+
auto iterator = sh_map.find(N);
147211

148-
if (I != sh_map.end())
212+
if (iterator != sh_map.end())
149213
{
150-
sh_map.erase(I);
214+
sh_map.erase(iterator);
151215
return;
152216
}
153217
Msg("! ERROR: Failed to find compiled geometry shader '%s'", *sh->cName);

src/Layers/xrRenderDX10/dx10ResourceManager_Resources.cpp

Lines changed: 3 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
#include "Layers/xrRenderDX10/dx10ConstantBuffer.h"
2121
#include "Layers/xrRender/ShaderResourceTraits.h"
2222

23+
SGS* CResourceManager::_CreateGS(LPCSTR Name) { return CreateShader<SGS>(Name); }
24+
void CResourceManager::_DeleteGS(const SGS* GS) { DestroyShader(GS); }
25+
2326
#ifdef USE_DX11
2427
SHS* CResourceManager::_CreateHS(LPCSTR Name) { return CreateShader<SHS>(Name); }
2528
void CResourceManager::_DeleteHS(const SHS* HS) { DestroyShader(HS); }
@@ -356,75 +359,6 @@ void CResourceManager::_DeletePS(const SPS* ps)
356359
Msg("! ERROR: Failed to find compiled pixel-shader '%s'", *ps->cName);
357360
}
358361

359-
//--------------------------------------------------------------------------------------------------------------
360-
SGS* CResourceManager::_CreateGS(LPCSTR name)
361-
{
362-
LPSTR N = LPSTR(name);
363-
map_GS::iterator I = m_gs.find(N);
364-
if (I != m_gs.end())
365-
return I->second;
366-
else
367-
{
368-
SGS* _gs = new SGS();
369-
_gs->dwFlags |= xr_resource_flagged::RF_REGISTERED;
370-
m_gs.insert(std::make_pair(_gs->set_name(name), _gs));
371-
if (0 == xr_stricmp(name, "null"))
372-
{
373-
_gs->sh = NULL;
374-
return _gs;
375-
}
376-
377-
// Open file
378-
string_path cname;
379-
strconcat(sizeof(cname), cname, GEnv.Render->getShaderPath(), name, ".gs");
380-
FS.update_path(cname, "$game_shaders$", cname);
381-
382-
// duplicate and zero-terminate
383-
IReader* file = FS.r_open(cname);
384-
// TODO: DX10: HACK: Implement all shaders. Remove this for PS
385-
if (!file)
386-
{
387-
string1024 tmp;
388-
// TODO: HACK: Test failure
389-
// Memory.mem_compact();
390-
xr_sprintf(tmp, "DX10: %s is missing. Replace with stub_default.gs", cname);
391-
Msg(tmp);
392-
strconcat(sizeof(cname), cname, GEnv.Render->getShaderPath(), "stub_default", ".gs");
393-
FS.update_path(cname, "$game_shaders$", cname);
394-
file = FS.r_open(cname);
395-
}
396-
R_ASSERT2(file, cname);
397-
398-
// Select target
399-
LPCSTR c_target = "gs_4_0";
400-
LPCSTR c_entry = "main";
401-
402-
HRESULT const _hr = GEnv.Render->shader_compile(name, (DWORD const*)file->pointer(), file->length(),
403-
c_entry, c_target, D3D10_SHADER_PACK_MATRIX_ROW_MAJOR, (void*&)_gs);
404-
405-
VERIFY(SUCCEEDED(_hr));
406-
407-
FS.r_close(file);
408-
409-
CHECK_OR_EXIT(!FAILED(_hr), "Your video card doesn't meet game requirements.\n\nTry to lower game settings.");
410-
411-
return _gs;
412-
}
413-
}
414-
void CResourceManager::_DeleteGS(const SGS* gs)
415-
{
416-
if (0 == (gs->dwFlags & xr_resource_flagged::RF_REGISTERED))
417-
return;
418-
LPSTR N = LPSTR(*gs->cName);
419-
map_GS::iterator I = m_gs.find(N);
420-
if (I != m_gs.end())
421-
{
422-
m_gs.erase(I);
423-
return;
424-
}
425-
Msg("! ERROR: Failed to find compiled geometry shader '%s'", *gs->cName);
426-
}
427-
428362
//--------------------------------------------------------------------------------------------------------------
429363
static BOOL dcl_equal(D3DVERTEXELEMENT9* a, D3DVERTEXELEMENT9* b)
430364
{

src/Layers/xrRenderPC_R3/r3.cpp

Lines changed: 34 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "Layers/xrRender/dxWallMarkArray.h"
1313
#include "Layers/xrRender/dxUIShader.h"
1414
#include "Layers/xrRenderDX10/3DFluid/dx103DFluidManager.h"
15+
#include "Layers/xrRender/ShaderResourceTraits.h"
1516
#include "D3DX10Core.h"
1617

1718
CRender RImplementation;
@@ -758,8 +759,40 @@ void CRender::DumpStatistics(IGameFont& font, IPerformanceAlert* alert)
758759
Sectors_xrc.DumpStatistics(font, alert);
759760
}
760761

762+
template <typename T>
763+
static HRESULT create_shader(LPCSTR const pTarget, DWORD const* buffer, u32 const buffer_size, LPCSTR const file_name,
764+
T*& result, bool const disasm)
765+
{
766+
// XXX: disasm it
767+
768+
result->sh = ShaderTypeTraits<T>::CreateHWShader(buffer, buffer_size);
769+
770+
ID3DShaderReflection* pReflection = 0;
771+
772+
#ifdef USE_DX11
773+
HRESULT const _hr = D3DReflect(buffer, buffer_size, IID_ID3DShaderReflection, (void**)&pReflection);
774+
#else
775+
HRESULT const _hr = D3D10ReflectShader(buffer, buffer_size, &pReflection);
776+
#endif
777+
778+
if (SUCCEEDED(_hr) && pReflection)
779+
{
780+
// Parse constant table data
781+
result->constants.parse(pReflection, ShaderTypeTraits<T>::GetShaderDest());
782+
783+
_RELEASE(pReflection);
784+
}
785+
else
786+
{
787+
Msg("! D3DReflectShader %s hr == 0x%08x", file_name, _hr);
788+
}
789+
790+
return _hr;
791+
}
792+
761793
static HRESULT create_shader(LPCSTR const pTarget, DWORD const* buffer, u32 const buffer_size, LPCSTR const file_name, void*& result, bool const disasm)
762794
{
795+
// XXX: what's going on with casts here???
763796
HRESULT _result = E_FAIL;
764797
if (pTarget[0] == 'p')
765798
{
@@ -852,41 +885,7 @@ static HRESULT create_shader(LPCSTR const pTarget, DWORD const* buffer, u32 cons
852885
}
853886
else if (pTarget[0] == 'g')
854887
{
855-
SGS* sgs_result = (SGS*)result;
856-
#ifdef USE_DX11
857-
_result = HW.pDevice->CreateGeometryShader(buffer, buffer_size, 0, &sgs_result->sh);
858-
#else // #ifdef USE_DX11
859-
_result = HW.pDevice->CreateGeometryShader(buffer, buffer_size, &sgs_result->sh);
860-
#endif // #ifdef USE_DX11
861-
if (!SUCCEEDED(_result))
862-
{
863-
Log("! GS: ", file_name);
864-
Msg("! CreateGeometryShaderhr == 0x%08x", _result);
865-
return E_FAIL;
866-
}
867-
868-
ID3DShaderReflection* pReflection = 0;
869-
870-
#ifdef USE_DX11
871-
_result = D3DReflect(buffer, buffer_size, IID_ID3DShaderReflection, (void**)&pReflection);
872-
#else
873-
_result = D3D10ReflectShader(buffer, buffer_size, &pReflection);
874-
#endif
875-
876-
// Parse constant, texture, sampler binding
877-
// Store input signature blob
878-
if (SUCCEEDED(_result) && pReflection)
879-
{
880-
// Let constant table parse it's data
881-
sgs_result->constants.parse(pReflection, RC_dest_geometry);
882-
883-
_RELEASE(pReflection);
884-
}
885-
else
886-
{
887-
Log("! PS: ", file_name);
888-
Msg("! D3DReflectShader hr == 0x%08x", _result);
889-
}
888+
_result = create_shader(pTarget, buffer, buffer_size, file_name, (SGS*&)result, disasm);
890889
}
891890
else
892891
{

0 commit comments

Comments
 (0)