2
0
mirror of https://github.com/rehlds/rehlds.git synced 2024-12-29 08:05:50 +03:00

Allow build rehlds without x86 delta jit (#546)

This commit is contained in:
theAsmodai 2017-12-09 17:08:29 +03:00 committed by Dmitry Novikov
parent fd64218ecd
commit aac529d2e4
7 changed files with 107 additions and 36 deletions

View File

@ -184,11 +184,11 @@ void setupToolchain(NativeBinarySpec b) {
} }
if (unitTestExecutable) { if (unitTestExecutable) {
cfg.singleDefines 'REHLDS_UNIT_TESTS', 'REHLDS_SSE' cfg.singleDefines 'REHLDS_UNIT_TESTS', 'REHLDS_SSE', 'REHLDS_JIT'
} }
if (rehldsFixes) { if (rehldsFixes) {
cfg.singleDefines 'REHLDS_FIXES', 'REHLDS_SSE', 'REHLDS_CHECKS', 'HAVE_OPT_STRTOOLS' cfg.singleDefines 'REHLDS_FIXES', 'REHLDS_SSE', 'REHLDS_JIT', 'REHLDS_CHECKS', 'HAVE_OPT_STRTOOLS'
} }
ToolchainConfigUtils.apply(project, cfg, b) ToolchainConfigUtils.apply(project, cfg, b)

View File

@ -383,7 +383,7 @@ void EXT_FUNC DELTA_UnsetField(struct delta_s *pFields, const char *fieldname)
void EXT_FUNC DELTA_SetFieldByIndex(struct delta_s *pFields, int fieldNumber) void EXT_FUNC DELTA_SetFieldByIndex(struct delta_s *pFields, int fieldNumber)
{ {
#if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES) #if (defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)) && defined REHLDS_JIT
DELTAJit_SetFieldByIndex(pFields, fieldNumber); DELTAJit_SetFieldByIndex(pFields, fieldNumber);
#else #else
pFields->pdd[fieldNumber].flags |= FDT_MARK; pFields->pdd[fieldNumber].flags |= FDT_MARK;
@ -392,7 +392,7 @@ void EXT_FUNC DELTA_SetFieldByIndex(struct delta_s *pFields, int fieldNumber)
void EXT_FUNC DELTA_UnsetFieldByIndex(struct delta_s *pFields, int fieldNumber) void EXT_FUNC DELTA_UnsetFieldByIndex(struct delta_s *pFields, int fieldNumber)
{ {
#if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES) #if (defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)) && defined REHLDS_JIT
DELTAJit_UnsetFieldByIndex(pFields, fieldNumber); DELTAJit_UnsetFieldByIndex(pFields, fieldNumber);
#else #else
pFields->pdd[fieldNumber].flags &= ~FDT_MARK; pFields->pdd[fieldNumber].flags &= ~FDT_MARK;
@ -407,11 +407,14 @@ void DELTA_ClearFlags(delta_t *pFields)
{ {
pitem->flags = 0; pitem->flags = 0;
} }
#if defined REHLDS_FIXES && !defined REHLDS_JIT
pFields->originalMarkedFieldsMask.u64 = 0;
#endif
} }
int DELTA_TestDelta(unsigned char *from, unsigned char *to, delta_t *pFields) int DELTA_TestDelta(unsigned char *from, unsigned char *to, delta_t *pFields)
{ {
#if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES) #if (defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)) && defined REHLDSJIT
return DELTAJit_TestDelta(from, to, pFields); return DELTAJit_TestDelta(from, to, pFields);
#else #else
int i; int i;
@ -562,6 +565,11 @@ void DELTA_MarkSendFields(unsigned char *from, unsigned char *to, delta_t *pFiel
Con_Printf("%s: Bad field type %i\n", __func__, fieldType); Con_Printf("%s: Bad field type %i\n", __func__, fieldType);
break; break;
} }
#if defined REHLDS_FIXES && !defined REHLDS_JIT
if (pTest->flags & FDT_MARK)
pFields->originalMarkedFieldsMask.u32[i >> 5] |= (1 << (i & 31));
#endif
} }
if (pFields->conditionalencode) if (pFields->conditionalencode)
pFields->conditionalencode(pFields, from, to); pFields->conditionalencode(pFields, from, to);
@ -599,7 +607,7 @@ void DELTA_SetSendFlagBits(delta_t *pFields, int *bits, int *bytecount)
qboolean DELTA_IsFieldMarked(delta_t* pFields, int fieldNumber) qboolean DELTA_IsFieldMarked(delta_t* pFields, int fieldNumber)
{ {
#if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES) #if (defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)) && defined REHLDS_JIT
return DELTAJit_IsFieldMarked(pFields, fieldNumber); return DELTAJit_IsFieldMarked(pFields, fieldNumber);
#else #else
return pFields->pdd[fieldNumber].flags & FDT_MARK; return pFields->pdd[fieldNumber].flags & FDT_MARK;
@ -725,7 +733,7 @@ qboolean DELTA_CheckDelta(unsigned char *from, unsigned char *to, delta_t *pFiel
{ {
qboolean sendfields; qboolean sendfields;
#if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES) #if (defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)) && defined REHLDS_JIT
sendfields = DELTAJit_Fields_Clear_Mark_Check(from, to, pFields, NULL); sendfields = DELTAJit_Fields_Clear_Mark_Check(from, to, pFields, NULL);
#else #else
DELTA_ClearFlags(pFields); DELTA_ClearFlags(pFields);
@ -740,7 +748,7 @@ NOINLINE qboolean DELTA_WriteDelta(unsigned char *from, unsigned char *to, qbool
{ {
qboolean sendfields; qboolean sendfields;
#if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES) #if (defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)) && defined REHLDS_JIT
sendfields = DELTAJit_Fields_Clear_Mark_Check(from, to, pFields, NULL); sendfields = DELTAJit_Fields_Clear_Mark_Check(from, to, pFields, NULL);
#else // REHLDS_OPT_PEDANTIC || REHLDS_FIXES #else // REHLDS_OPT_PEDANTIC || REHLDS_FIXES
DELTA_ClearFlags(pFields); DELTA_ClearFlags(pFields);
@ -754,9 +762,57 @@ NOINLINE qboolean DELTA_WriteDelta(unsigned char *from, unsigned char *to, qbool
#ifdef REHLDS_FIXES //Fix for https://github.com/dreamstalker/rehlds/issues/24 #ifdef REHLDS_FIXES //Fix for https://github.com/dreamstalker/rehlds/issues/24
qboolean DELTA_WriteDeltaForceMask(unsigned char *from, unsigned char *to, qboolean force, delta_t *pFields, void(*callback)(void), void* pForceMask) { qboolean DELTA_WriteDeltaForceMask(unsigned char *from, unsigned char *to, qboolean force, delta_t *pFields, void(*callback)(void), void* pForceMask) {
#ifdef REHLDS_JIT
qboolean sendfields = DELTAJit_Fields_Clear_Mark_Check(from, to, pFields, pForceMask); qboolean sendfields = DELTAJit_Fields_Clear_Mark_Check(from, to, pFields, pForceMask);
_DELTA_WriteDelta(from, to, force, pFields, callback, sendfields); _DELTA_WriteDelta(from, to, force, pFields, callback, sendfields);
return sendfields; return sendfields;
#else
DELTA_ClearFlags(pFields);
// force fields
if (pForceMask) {
delta_description_t *pTest;
int i;
delta_marked_mask_t forceMask = *(delta_marked_mask_t *)pForceMask;
for (i = 0, pTest = pFields->pdd; i < pFields->fieldCount; i++, pTest++) {
int mark = (forceMask.u32[i >> 5] & (1 << (i & 31))) ? FDT_MARK : 0;
pTest->flags |= mark;
}
}
DELTA_MarkSendFields(from, to, pFields);
qboolean sendfields = DELTA_CountSendFields(pFields);
_DELTA_WriteDelta(from, to, force, pFields, callback, sendfields);
return sendfields;
#endif
}
uint64 DELTA_GetOriginalMask(delta_t* pFields)
{
#ifdef REHLDS_JIT
return DELTAJit_GetOriginalMask(pFields);
#else
return pFields->originalMarkedFieldsMask.u64;
#endif
}
uint64 DELTA_GetMaskU64(delta_t* pFields)
{
#ifdef REHLDS_JIT
return DELTAJit_GetMaskU64(pFields);
#else
delta_description_t *pTest;
int i;
delta_marked_mask_t mask = {};
for (i = 0, pTest = pFields->pdd; i < pFields->fieldCount; i++, pTest++) {
if (pTest->flags & FDT_MARK)
mask.u32[i >> 5] |= (1 << (i & 31));
}
return mask.u64;
#endif
} }
#endif #endif
@ -768,7 +824,7 @@ qboolean _DELTA_WriteDelta(unsigned char *from, unsigned char *to, qboolean forc
if (sendfields || force) if (sendfields || force)
{ {
#if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES) #if (defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)) && defined REHLDS_JIT
DELTAJit_SetSendFlagBits(pFields, bits, &bytecount); DELTAJit_SetSendFlagBits(pFields, bits, &bytecount);
#else #else
DELTA_SetSendFlagBits(pFields, bits, &bytecount); DELTA_SetSendFlagBits(pFields, bits, &bytecount);

View File

@ -72,6 +72,12 @@ typedef struct delta_description_s
class CDeltaJit; class CDeltaJit;
union delta_marked_mask_t {
uint8 u8[8];
uint32 u32[2];
uint64 u64;
};
typedef struct delta_s typedef struct delta_s
{ {
int dynamic; int dynamic;
@ -80,8 +86,10 @@ typedef struct delta_s
encoder_t conditionalencode; encoder_t conditionalencode;
delta_description_t *pdd; delta_description_t *pdd;
#ifdef REHLDS_FIXES #if defined(REHLDS_JIT)
CDeltaJit* jit; CDeltaJit* jit;
#elif defined(REHLDS_FIXES)
delta_marked_mask_t originalMarkedFieldsMask;
#endif #endif
} delta_t; } delta_t;
@ -136,6 +144,8 @@ qboolean DELTA_CheckDelta(unsigned char *from, unsigned char *to, delta_t *pFiel
#ifdef REHLDS_FIXES //Fix for https://github.com/dreamstalker/rehlds/issues/24 #ifdef REHLDS_FIXES //Fix for https://github.com/dreamstalker/rehlds/issues/24
qboolean DELTA_WriteDeltaForceMask(unsigned char *from, unsigned char *to, qboolean force, delta_t *pFields, void(*callback)(void), void* pForceMask); qboolean DELTA_WriteDeltaForceMask(unsigned char *from, unsigned char *to, qboolean force, delta_t *pFields, void(*callback)(void), void* pForceMask);
uint64 DELTA_GetOriginalMask(delta_t* pFields);
uint64 DELTA_GetMaskU64(delta_t* pFields);
#endif #endif
qboolean DELTA_WriteDelta(unsigned char *from, unsigned char *to, qboolean force, delta_t *pFields, void(*callback)(void)); qboolean DELTA_WriteDelta(unsigned char *from, unsigned char *to, qboolean force, delta_t *pFields, void(*callback)(void));

View File

@ -29,6 +29,7 @@
#include "precompiled.h" #include "precompiled.h"
#include "jitasm.h" #include "jitasm.h"
#ifdef REHLDS_JIT
CDeltaJitRegistry g_DeltaJitRegistry; CDeltaJitRegistry g_DeltaJitRegistry;
uint32 DELTAJIT_CreateMask(int startBit, int endBit) { uint32 DELTAJIT_CreateMask(int startBit, int endBit) {
@ -686,11 +687,11 @@ void CDeltaJitRegistry::CreateAndRegisterDeltaJIT(delta_t* delta) {
CDeltaClearMarkFieldsJIT* cleanMarkCheckFunc = new CDeltaClearMarkFieldsJIT(&data); CDeltaClearMarkFieldsJIT* cleanMarkCheckFunc = new CDeltaClearMarkFieldsJIT(&data);
cleanMarkCheckFunc->Assemble(); cleanMarkCheckFunc->Assemble();
cleanMarkCheckFunc->jitdesc = NULL; cleanMarkCheckFunc->jitdesc = nullptr;
CDeltaTestDeltaJIT* testDeltaFunc = new CDeltaTestDeltaJIT(&data); CDeltaTestDeltaJIT* testDeltaFunc = new CDeltaTestDeltaJIT(&data);
testDeltaFunc->Assemble(); testDeltaFunc->Assemble();
testDeltaFunc->jitdesc = NULL; testDeltaFunc->jitdesc = nullptr;
// align to 16 // align to 16
CDeltaJit* deltaJit = new CDeltaJit(delta, cleanMarkCheckFunc, testDeltaFunc); CDeltaJit* deltaJit = new CDeltaJit(delta, cleanMarkCheckFunc, testDeltaFunc);
@ -731,13 +732,13 @@ void DELTAJit_SetSendFlagBits(delta_t *pFields, int *bits, int *bytecount) {
*bytecount = deltaJit->markedFieldsMaskSize; *bytecount = deltaJit->markedFieldsMaskSize;
} }
void DELTAJit_SetFieldByIndex(struct delta_s *pFields, int fieldNumber) void DELTAJit_SetFieldByIndex(delta_t *pFields, int fieldNumber)
{ {
CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__func__, pFields); CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__func__, pFields);
deltaJit->marked_fields_mask.u32[fieldNumber >> 5] |= (1 << (fieldNumber & 31)); deltaJit->marked_fields_mask.u32[fieldNumber >> 5] |= (1 << (fieldNumber & 31));
} }
void DELTAJit_UnsetFieldByIndex(struct delta_s *pFields, int fieldNumber) void DELTAJit_UnsetFieldByIndex(delta_t *pFields, int fieldNumber)
{ {
CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__func__, pFields); CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__func__, pFields);
deltaJit->marked_fields_mask.u32[fieldNumber >> 5] &= ~(1 << (fieldNumber & 31)); deltaJit->marked_fields_mask.u32[fieldNumber >> 5] &= ~(1 << (fieldNumber & 31));
@ -777,3 +778,4 @@ void CDeltaJitRegistry::Cleanup() {
} }
#endif #endif
} }
#endif

View File

@ -30,6 +30,7 @@
#include "maintypes.h" #include "maintypes.h"
#ifdef REHLDS_JIT
const int DELTAJIT_MAX_BLOCKS = 32; const int DELTAJIT_MAX_BLOCKS = 32;
const int DELTAJIT_MAX_FIELDS = 56; const int DELTAJIT_MAX_FIELDS = 56;
@ -87,23 +88,16 @@ public:
void Cleanup(); void Cleanup();
}; };
union delta_marked_mask_t {
uint8 u8[8];
uint32 u32[2];
uint64 u64;
};
extern CDeltaJitRegistry g_DeltaJitRegistry; extern CDeltaJitRegistry g_DeltaJitRegistry;
extern int DELTAJit_Fields_Clear_Mark_Check(unsigned char *from, unsigned char *to, delta_t *pFields, void* pForceMarkMask); extern int DELTAJit_Fields_Clear_Mark_Check(unsigned char *from, unsigned char *to, delta_t *pFields, void* pForceMarkMask);
extern int DELTAJit_TestDelta(unsigned char *from, unsigned char *to, delta_t *pFields); extern int DELTAJit_TestDelta(unsigned char *from, unsigned char *to, delta_t *pFields);
extern void DELTAJit_SetSendFlagBits(delta_t *pFields, int *bits, int *bytecount); extern void DELTAJit_SetSendFlagBits(delta_t *pFields, int *bits, int *bytecount);
extern void DELTAJit_SetFieldByIndex(struct delta_s *pFields, int fieldNumber); extern void DELTAJit_SetFieldByIndex(delta_t *pFields, int fieldNumber);
extern void DELTAJit_UnsetFieldByIndex(struct delta_s *pFields, int fieldNumber); extern void DELTAJit_UnsetFieldByIndex(delta_t *pFields, int fieldNumber);
extern qboolean DELTAJit_IsFieldMarked(delta_t* pFields, int fieldNumber); extern qboolean DELTAJit_IsFieldMarked(delta_t* pFields, int fieldNumber);
/* Returns original mask, before it was changed by the conditional encoder */ /* Returns original mask, before it was changed by the conditional encoder */
extern uint64 DELTAJit_GetOriginalMask(delta_t* pFields); extern uint64 DELTAJit_GetOriginalMask(delta_t* pFields);
extern uint64 DELTAJit_GetMaskU64(delta_t* pFields); extern uint64 DELTAJit_GetMaskU64(delta_t* pFields);
#endif

View File

@ -4435,8 +4435,8 @@ int SV_CreatePacketEntities_internal(sv_delta_t type, client_t *client, packet_e
); );
baselineToIdx = -1; baselineToIdx = -1;
uint64 origMask = DELTAJit_GetOriginalMask(delta); uint64 origMask = DELTA_GetOriginalMask(delta);
uint64 usedMask = DELTAJit_GetMaskU64(delta); uint64 usedMask = DELTA_GetMaskU64(delta);
uint64 diffMask = origMask ^ usedMask; uint64 diffMask = origMask ^ usedMask;
//Remember changed fields that was marked in original mask, but unmarked by the conditional encoder //Remember changed fields that was marked in original mask, but unmarked by the conditional encoder
@ -7717,7 +7717,7 @@ void SV_RegisterDelta(char *name, char *loadfile)
p->next = g_sv_delta; p->next = g_sv_delta;
g_sv_delta = p; g_sv_delta = p;
#if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES) #if (defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)) && defined REHLDS_JIT
g_DeltaJitRegistry.CreateAndRegisterDeltaJIT(pdesc); g_DeltaJitRegistry.CreateAndRegisterDeltaJIT(pdesc);
#endif #endif
} }
@ -7763,7 +7763,7 @@ void SV_InitDeltas(void)
Sys_Error("%s: No usercmd_t encoder on server!\n", __func__); Sys_Error("%s: No usercmd_t encoder on server!\n", __func__);
#endif #endif
#if defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES) #if (defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)) && defined REHLDS_JIT
g_DeltaJitRegistry.CreateAndRegisterDeltaJIT(&g_MetaDelta[0]); g_DeltaJitRegistry.CreateAndRegisterDeltaJIT(&g_MetaDelta[0]);
#endif #endif
} }
@ -7966,7 +7966,9 @@ void SV_Init(void)
void SV_Shutdown(void) void SV_Shutdown(void)
{ {
#if (defined(REHLDS_OPT_PEDANTIC) || defined(REHLDS_FIXES)) && defined REHLDS_JIT
g_DeltaJitRegistry.Cleanup(); g_DeltaJitRegistry.Cleanup();
#endif
delta_info_t *p = g_sv_delta; delta_info_t *p = g_sv_delta;
while (p) while (p)
{ {

View File

@ -63,10 +63,13 @@ NOINLINE void _FillTestDelta(delta_test_struct_t* data, unsigned char val) {
NOINLINE qboolean _DoMarkFields(void* src, void* dst, delta_t* delta, bool useJit) { NOINLINE qboolean _DoMarkFields(void* src, void* dst, delta_t* delta, bool useJit) {
qboolean sendfields; qboolean sendfields;
#ifdef REHLDS_JIT
if (useJit) { if (useJit) {
DELTA_ClearFlags(delta); DELTA_ClearFlags(delta);
return DELTAJit_Fields_Clear_Mark_Check((unsigned char*)src, (unsigned char*)dst, delta, NULL); return DELTAJit_Fields_Clear_Mark_Check((unsigned char*)src, (unsigned char*)dst, delta, NULL);
} else { } else
#endif
{
DELTA_ClearFlags(delta); DELTA_ClearFlags(delta);
DELTA_MarkSendFields((unsigned char*)src, (unsigned char*)dst, delta); DELTA_MarkSendFields((unsigned char*)src, (unsigned char*)dst, delta);
sendfields = DELTA_CountSendFields(delta); sendfields = DELTA_CountSendFields(delta);
@ -140,9 +143,12 @@ NOINLINE void _MarkAndEnsureCorrectResults(const char* action, delta_t* delta, v
delta_marked_mask_t returnedMask; delta_marked_mask_t returnedMask;
int returnedBytecount; int returnedBytecount;
#ifdef REHLDS_JIT
if (useJit) { if (useJit) {
DELTAJit_SetSendFlagBits(delta, (int*)returnedMask.u32, &returnedBytecount); DELTAJit_SetSendFlagBits(delta, (int*)returnedMask.u32, &returnedBytecount);
} else { } else
#endif
{
DELTA_SetSendFlagBits(delta, (int*)returnedMask.u32, &returnedBytecount); DELTA_SetSendFlagBits(delta, (int*)returnedMask.u32, &returnedBytecount);
} }
@ -159,10 +165,13 @@ NOINLINE void _MarkAndEnsureCorrectResults(const char* action, delta_t* delta, v
NOINLINE void _GetBitmaskAndBytecount(delta_t* delta, int* bits, int* bytecount, int usejit) { NOINLINE void _GetBitmaskAndBytecount(delta_t* delta, int* bits, int* bytecount, int usejit) {
#ifdef REHLDS_JIT
if (usejit) { if (usejit) {
DELTAJit_SetSendFlagBits(delta, bits, bytecount); DELTAJit_SetSendFlagBits(delta, bits, bytecount);
} }
else { else
#endif
{
DELTA_SetSendFlagBits(delta, bits, bytecount); DELTA_SetSendFlagBits(delta, bits, bytecount);
} }
} }
@ -209,8 +218,9 @@ NOINLINE delta_t* _CreateTestDeltaDesc() {
dinfo->next = g_sv_delta; dinfo->next = g_sv_delta;
g_sv_delta = dinfo; g_sv_delta = dinfo;
#ifdef REHLDS_JIT
g_DeltaJitRegistry.CreateAndRegisterDeltaJIT(delta); g_DeltaJitRegistry.CreateAndRegisterDeltaJIT(delta);
#endif
return delta; return delta;
}; };
@ -345,11 +355,8 @@ TEST(TestDelta_Test, Delta, 1000) {
testdata[2].f_18 = 2.0; testdata[2].f_18 = 2.0;
testdata[2].wb_20 = 2.0; testdata[2].wb_20 = 2.0;
strcpy(testdata[2].s_24, "TestDelta_Test" ); strcpy(testdata[2].s_24, "TestDelta_Test" );
#ifdef REHLDS_FIXES
result[2] = delta->pdd[10].significant_bits + delta->pdd[12].significant_bits + strlen(testdata[2].s_24) * 8 + 8 + (13 / 8 * 8 + 8); result[2] = delta->pdd[10].significant_bits + delta->pdd[12].significant_bits + strlen(testdata[2].s_24) * 8 + 8 + (13 / 8 * 8 + 8);
#else
result[2] = delta->pdd[10].significant_bits + delta->pdd[12].significant_bits + (13 / 8 * 8 + 8);
#endif
// change byte + int + float + short // change byte + int + float + short
testdata[3].b_4D = 4; testdata[3].b_4D = 4;