@@ -758,319 +758,3 @@ void CRender::DumpStatistics(IGameFont& font, IPerformanceAlert* alert)
758758 HOM.DumpStatistics (font, alert);
759759 Sectors_xrc.DumpStatistics (font, alert);
760760}
761-
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- result->sh = ShaderTypeTraits<T>::CreateHWShader (buffer, buffer_size);
767-
768- LPCVOID data = nullptr ;
769-
770- HRESULT const _hr = D3DXFindShaderComment (buffer, MAKEFOURCC (' C' , ' T' , ' A' , ' B' ), &data, nullptr );
771-
772- if (SUCCEEDED (_hr) && data)
773- {
774- // Parse constant table data
775- LPD3DXSHADER_CONSTANTTABLE pConstants = LPD3DXSHADER_CONSTANTTABLE (data);
776- result->constants .parse (pConstants, ShaderTypeTraits<T>::GetShaderDest ());
777- }
778- else
779- Msg (" ! D3DXFindShaderComment %s hr == 0x%08x" , file_name, _hr);
780-
781- if (disasm)
782- {
783- ID3DXBuffer* disasm = nullptr ;
784- D3DXDisassembleShader (LPDWORD (buffer), FALSE , nullptr , &disasm);
785- string_path dname;
786- strconcat (sizeof (dname), dname, " disasm\\ " , file_name, (' v' == pTarget[0 ]) ? " .vs" : " .ps" );
787- IWriter* W = FS.w_open (" $logs$" , dname);
788- W->w (disasm->GetBufferPointer (), disasm->GetBufferSize ());
789- FS.w_close (W);
790- _RELEASE (disasm);
791- }
792-
793- return _hr;
794- }
795-
796- inline HRESULT create_shader (LPCSTR const pTarget, DWORD const * buffer, u32 const buffer_size, LPCSTR const file_name, void *& result, bool const disasm)
797- {
798- if (pTarget[0 ] == ' p' )
799- return create_shader (pTarget, buffer, buffer_size, file_name, (SPS*&)result, disasm);
800-
801- if (pTarget[0 ] == ' v' )
802- return create_shader (pTarget, buffer, buffer_size, file_name, (SVS*&)result, disasm);
803-
804- NODEFAULT;
805- return E_FAIL;
806- }
807-
808- class includer : public ID3DXInclude
809- {
810- public:
811- HRESULT __stdcall Open (
812- D3DXINCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID* ppData, UINT* pBytes)
813- {
814- string_path pname;
815- strconcat (sizeof (pname), pname, GEnv.Render ->getShaderPath (), pFileName);
816- IReader* R = FS.r_open (" $game_shaders$" , pname);
817- if (nullptr == R)
818- {
819- // possibly in shared directory or somewhere else - open directly
820- R = FS.r_open (" $game_shaders$" , pFileName);
821- if (nullptr == R)
822- return E_FAIL;
823- }
824-
825- // duplicate and zero-terminate
826- u32 size = R->length ();
827- u8 * data = xr_alloc<u8 >(size + 1 );
828- CopyMemory (data, R->pointer (), size);
829- data[size] = 0 ;
830- FS.r_close (R);
831-
832- *ppData = data;
833- *pBytes = size;
834- return D3D_OK;
835- }
836- HRESULT __stdcall Close (LPCVOID pData)
837- {
838- xr_free (pData);
839- return D3D_OK;
840- }
841- };
842-
843- static inline bool match_shader_id (
844- LPCSTR const debug_shader_id, LPCSTR const full_shader_id, FS_FileSet const & file_set, string_path& result);
845-
846- HRESULT CRender::shader_compile (LPCSTR name, DWORD const * pSrcData, UINT SrcDataLen, LPCSTR pFunctionName,
847- LPCSTR pTarget, DWORD Flags, void *& result)
848- {
849- D3DXMACRO defines[128 ];
850- int def_it = 0 ;
851-
852- char sh_name[MAX_PATH] = " " ;
853- u32 len = 0 ;
854- // options
855- if (o.forceskinw )
856- {
857- defines[def_it].Name = " SKIN_COLOR" ;
858- defines[def_it].Definition = " 1" ;
859- def_it++;
860- }
861- sh_name[len] = ' 0' + char (o.forceskinw );
862- ++len;
863-
864- // skinning
865- if (m_skinning < 0 )
866- {
867- defines[def_it].Name = " SKIN_NONE" ;
868- defines[def_it].Definition = " 1" ;
869- def_it++;
870- sh_name[len] = ' 1' ;
871- ++len;
872- }
873- else
874- {
875- sh_name[len] = ' 0' ;
876- ++len;
877- }
878-
879- if (0 == m_skinning)
880- {
881- defines[def_it].Name = " SKIN_0" ;
882- defines[def_it].Definition = " 1" ;
883- def_it++;
884- }
885- sh_name[len] = ' 0' + char (0 == m_skinning);
886- ++len;
887-
888- if (1 == m_skinning)
889- {
890- defines[def_it].Name = " SKIN_1" ;
891- defines[def_it].Definition = " 1" ;
892- def_it++;
893- }
894- sh_name[len] = ' 0' + char (1 == m_skinning);
895- ++len;
896-
897- if (2 == m_skinning)
898- {
899- defines[def_it].Name = " SKIN_2" ;
900- defines[def_it].Definition = " 1" ;
901- def_it++;
902- }
903- sh_name[len] = ' 0' + char (2 == m_skinning);
904- ++len;
905-
906- if (3 == m_skinning)
907- {
908- defines[def_it].Name = " SKIN_3" ;
909- defines[def_it].Definition = " 1" ;
910- def_it++;
911- }
912- sh_name[len] = ' 0' + char (3 == m_skinning);
913- ++len;
914-
915- if (4 == m_skinning)
916- {
917- defines[def_it].Name = " SKIN_4" ;
918- defines[def_it].Definition = " 1" ;
919- def_it++;
920- }
921- sh_name[len] = ' 0' + char (4 == m_skinning);
922- ++len;
923-
924- sh_name[len] = ' \0 ' ;
925-
926- // finish
927- defines[def_it].Name = nullptr ;
928- defines[def_it].Definition = nullptr ;
929- def_it++;
930- R_ASSERT (def_it < 128 );
931-
932- HRESULT _result = E_FAIL;
933-
934- string_path folder_name, folder;
935- xr_strcpy (folder, " r1\\ objects\\ r1\\ " );
936- xr_strcat (folder, name);
937- xr_strcat (folder, " ." );
938-
939- char extension[3 ];
940- strncpy_s (extension, pTarget, 2 );
941- xr_strcat (folder, extension);
942-
943- FS.update_path (folder_name, " $game_shaders$" , folder);
944- xr_strcat (folder_name, " \\ " );
945-
946- m_file_set.clear ();
947- FS.file_list (m_file_set, folder_name, FS_ListFiles | FS_RootOnly, " *" );
948-
949- string_path temp_file_name, file_name;
950- if (!match_shader_id (name, sh_name, m_file_set, temp_file_name))
951- {
952- string_path file;
953- xr_strcpy (file, " shaders_cache\\ r1\\ " );
954- xr_strcat (file, name);
955- xr_strcat (file, " ." );
956- xr_strcat (file, extension);
957- xr_strcat (file, " \\ " );
958- xr_strcat (file, sh_name);
959- FS.update_path (file_name, " $app_data_root$" , file);
960- }
961- else
962- {
963- xr_strcpy (file_name, folder_name);
964- xr_strcat (file_name, temp_file_name);
965- }
966-
967- if (FS.exist (file_name))
968- {
969- IReader* file = FS.r_open (file_name);
970- if (file->length () > 4 )
971- {
972- u32 crc = file->r_u32 ();
973- u32 crcComp = crc32 (file->pointer (), file->elapsed ());
974- if (crcComp == crc)
975- _result = create_shader (pTarget, (DWORD*)file->pointer (), file->elapsed (), file_name, result, o.disasm );
976- }
977- file->close ();
978- }
979-
980- if (FAILED (_result))
981- {
982- includer Includer;
983- LPD3DXBUFFER pShaderBuf = nullptr ;
984- LPD3DXBUFFER pErrorBuf = nullptr ;
985- LPD3DXCONSTANTTABLE pConstants = nullptr ;
986- LPD3DXINCLUDE pInclude = (LPD3DXINCLUDE)&Includer;
987-
988- _result = D3DXCompileShader ((LPCSTR)pSrcData, SrcDataLen, defines, pInclude, pFunctionName, pTarget,
989- Flags | D3DXSHADER_USE_LEGACY_D3DX9_31_DLL, &pShaderBuf, &pErrorBuf, &pConstants);
990- if (SUCCEEDED (_result))
991- {
992- IWriter* file = FS.w_open (file_name);
993- u32 crc = crc32 (pShaderBuf->GetBufferPointer (), pShaderBuf->GetBufferSize ());
994- file->w_u32 (crc);
995- file->w (pShaderBuf->GetBufferPointer (), (u32 )pShaderBuf->GetBufferSize ());
996- FS.w_close (file);
997-
998- _result = create_shader (pTarget, (DWORD*)pShaderBuf->GetBufferPointer (), pShaderBuf->GetBufferSize (),
999- file_name, result, o.disasm );
1000- }
1001- else
1002- {
1003- Log (" ! " , file_name);
1004- if (pErrorBuf)
1005- Log (" ! error: " , (LPCSTR)pErrorBuf->GetBufferPointer ());
1006- else
1007- Msg (" Can't compile shader hr=0x%08x" , _result);
1008- }
1009- }
1010-
1011- return _result;
1012- }
1013-
1014- static inline bool match_shader (
1015- LPCSTR const debug_shader_id, LPCSTR const full_shader_id, LPCSTR const mask, size_t const mask_length)
1016- {
1017- u32 const full_shader_id_length = xr_strlen (full_shader_id);
1018- R_ASSERT2 (full_shader_id_length == mask_length,
1019- make_string (" bad cache for shader %s, [%s], [%s]" , debug_shader_id, mask, full_shader_id));
1020- char const * i = full_shader_id;
1021- char const * const e = full_shader_id + full_shader_id_length;
1022- char const * j = mask;
1023- for (; i != e; ++i, ++j)
1024- {
1025- if (*i == *j)
1026- continue ;
1027-
1028- if (*j == ' _' )
1029- continue ;
1030-
1031- return false ;
1032- }
1033-
1034- return true ;
1035- }
1036-
1037- static inline bool match_shader_id (
1038- LPCSTR const debug_shader_id, LPCSTR const full_shader_id, FS_FileSet const & file_set, string_path& result)
1039- {
1040- #if 1
1041- strcpy_s ( result, " " );
1042- return false ;
1043- #else // #if 1
1044- #ifdef DEBUG
1045- LPCSTR temp = "";
1046- bool found = false;
1047- FS_FileSet::const_iterator i = file_set.begin();
1048- FS_FileSet::const_iterator const e = file_set.end();
1049- for (; i != e; ++i)
1050- {
1051- if (match_shader(debug_shader_id, full_shader_id, (*i).name.c_str(), (*i).name.size()))
1052- {
1053- VERIFY(!found);
1054- found = true;
1055- temp = (*i).name.c_str();
1056- }
1057- }
1058-
1059- xr_strcpy(result, temp);
1060- return found;
1061- #else // #ifdef DEBUG
1062- FS_FileSet::const_iterator i = file_set.begin();
1063- FS_FileSet::const_iterator const e = file_set.end();
1064- for (; i != e; ++i)
1065- {
1066- if (match_shader(debug_shader_id, full_shader_id, (*i).name.c_str(), (*i).name.size()))
1067- {
1068- xr_strcpy(result, (*i).name.c_str());
1069- return true;
1070- }
1071- }
1072-
1073- return false;
1074- #endif // #ifdef DEBUG
1075- #endif // #if 1
1076- }
0 commit comments