mirror of
https://github.com/rehlds/rehlds.git
synced 2025-01-04 02:55:50 +03:00
Merge pull request #23 from dreamstalker/delta_tests_improvements
Delta encoder tests: refactoring Added prefetches to delta and deltaJit
This commit is contained in:
commit
0b1f3af352
@ -3,20 +3,6 @@
|
|||||||
|
|
||||||
CDeltaJitRegistry g_DeltaJitRegistry;
|
CDeltaJitRegistry g_DeltaJitRegistry;
|
||||||
|
|
||||||
bool deltajit_memblock::isEmpty() const
|
|
||||||
{
|
|
||||||
if (numFields == 0)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < numFields; i++)
|
|
||||||
{
|
|
||||||
if (fields[i].mask != 0)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 DELTAJIT_CreateMask(int startBit, int endBit) {
|
uint32 DELTAJIT_CreateMask(int startBit, int endBit) {
|
||||||
if (startBit < 0) startBit = 0;
|
if (startBit < 0) startBit = 0;
|
||||||
if (endBit < 0) endBit = 0;
|
if (endBit < 0) endBit = 0;
|
||||||
@ -83,7 +69,7 @@ void DELTAJIT_CreateDescription(delta_t* delta, deltajitdata_t &jitdesc) {
|
|||||||
jitdesc.numblocks = numMemBlocks;
|
jitdesc.numblocks = numMemBlocks;
|
||||||
jitdesc.numFields = delta->fieldCount;
|
jitdesc.numFields = delta->fieldCount;
|
||||||
|
|
||||||
//create descriptions (primitive types)
|
//create descriptions
|
||||||
for (int i = 0; i < delta->fieldCount; i++) {
|
for (int i = 0; i < delta->fieldCount; i++) {
|
||||||
delta_description_t* fieldDesc = &delta->pdd[i];
|
delta_description_t* fieldDesc = &delta->pdd[i];
|
||||||
|
|
||||||
@ -119,6 +105,25 @@ void DELTAJIT_CreateDescription(delta_t* delta, deltajitdata_t &jitdesc) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//calculate blocks that we should check
|
||||||
|
for (unsigned int i = 0; i < jitdesc.numblocks; i++) {
|
||||||
|
if (jitdesc.blocks[i].numFields > 0) {
|
||||||
|
jitdesc.itrBlocks[jitdesc.numItrBlocks].memblockId = i;
|
||||||
|
jitdesc.itrBlocks[jitdesc.numItrBlocks].memblock = &jitdesc.blocks[i];
|
||||||
|
jitdesc.itrBlocks[jitdesc.numItrBlocks].prefetchBlockId = -1;
|
||||||
|
jitdesc.numItrBlocks++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//decide which blocks we should prefetch
|
||||||
|
for (unsigned int i = 0; i < jitdesc.numItrBlocks; i++) {
|
||||||
|
unsigned int prefetchBlkId = (i + 1) * 4;
|
||||||
|
if (prefetchBlkId >= jitdesc.numblocks)
|
||||||
|
break;
|
||||||
|
|
||||||
|
jitdesc.itrBlocks[i].prefetchBlockId = prefetchBlkId;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class CDeltaClearMarkFieldsJIT;
|
class CDeltaClearMarkFieldsJIT;
|
||||||
@ -130,7 +135,7 @@ public:
|
|||||||
|
|
||||||
int markedFieldsMaskSize;
|
int markedFieldsMaskSize;
|
||||||
|
|
||||||
int marked_fields_mask[2];
|
delta_marked_mask_t marked_fields_mask;
|
||||||
int sse_highbits[2]; //High 64 bits for manipulating marked_fields_mask via SSE registers
|
int sse_highbits[2]; //High 64 bits for manipulating marked_fields_mask via SSE registers
|
||||||
|
|
||||||
CDeltaJit(delta_t* _delta, CDeltaClearMarkFieldsJIT* _cleanMarkCheckFunc);
|
CDeltaJit(delta_t* _delta, CDeltaClearMarkFieldsJIT* _cleanMarkCheckFunc);
|
||||||
@ -143,7 +148,7 @@ public:
|
|||||||
deltajitdata_t *jitdesc;
|
deltajitdata_t *jitdesc;
|
||||||
deltajit_marked_count_type_t countType;
|
deltajit_marked_count_type_t countType;
|
||||||
|
|
||||||
XmmReg marked_fields_mask = xmm5;
|
XmmReg marked_fields_mask = xmm7;
|
||||||
|
|
||||||
|
|
||||||
CDeltaClearMarkFieldsJIT(deltajitdata_t *_jitdesc, deltajit_marked_count_type_t _countType)
|
CDeltaClearMarkFieldsJIT(deltajitdata_t *_jitdesc, deltajit_marked_count_type_t _countType)
|
||||||
@ -258,43 +263,67 @@ CDeltaClearMarkFieldsJIT::Result CDeltaClearMarkFieldsJIT::main(Addr src, Addr d
|
|||||||
sub(esp, 12); //some local storage is required for precise DT_TIMEWINDOW marking
|
sub(esp, 12); //some local storage is required for precise DT_TIMEWINDOW marking
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
Registers usage:
|
||||||
|
esi = src
|
||||||
|
edi = dst
|
||||||
|
xmm0-xmm2: loaded src
|
||||||
|
xmm3-xmm5: loaded dst
|
||||||
|
xmm6: temp
|
||||||
|
xmm7: marked fields mask
|
||||||
|
*/
|
||||||
mov(esi, ptr[src]);
|
mov(esi, ptr[src]);
|
||||||
mov(edi, ptr[dst]);
|
mov(edi, ptr[dst]);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < jitdesc->numblocks; i++) {
|
int dataXmmCounter = 0; // from 0 to 2 => 3 pairs of registers
|
||||||
if (!jitdesc->blocks[i].isEmpty()) {
|
jitasm::Frontend::XmmReg src_xmm[3] = { xmm0, xmm1, xmm2 };
|
||||||
movdqu(xmm3, xmmword_ptr[esi + (i * 16)]);
|
jitasm::Frontend::XmmReg dst_xmm[3] = { xmm3, xmm4, xmm5 };
|
||||||
movdqu(xmm4, xmmword_ptr[edi + (i * 16)]);
|
// overall mask is in xmm7 (marked_fields_mask)
|
||||||
break;
|
auto xmm_tmp = xmm6;
|
||||||
}
|
|
||||||
|
|
||||||
|
if (jitdesc->numItrBlocks > 0) {
|
||||||
|
movdqu(src_xmm[0], xmmword_ptr[esi + (jitdesc->itrBlocks[0].memblockId * 16)]);
|
||||||
|
movdqu(dst_xmm[0], xmmword_ptr[edi + (jitdesc->itrBlocks[0].memblockId * 16)]);
|
||||||
|
}
|
||||||
|
if (jitdesc->numItrBlocks > 1) {
|
||||||
|
movdqu(src_xmm[1], xmmword_ptr[esi + (jitdesc->itrBlocks[1].memblockId * 16)]);
|
||||||
|
movdqu(dst_xmm[1], xmmword_ptr[edi + (jitdesc->itrBlocks[1].memblockId * 16)]);
|
||||||
|
}
|
||||||
|
if (jitdesc->numItrBlocks > 2) {
|
||||||
|
movdqu(src_xmm[2], xmmword_ptr[esi + (jitdesc->itrBlocks[2].memblockId * 16)]);
|
||||||
|
movdqu(dst_xmm[2], xmmword_ptr[edi + (jitdesc->itrBlocks[2].memblockId * 16)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto mask = ecx;
|
auto blockMask = ecx;
|
||||||
xor_(mask, mask);
|
xor_(blockMask, blockMask);
|
||||||
|
|
||||||
pxor(marked_fields_mask, marked_fields_mask);
|
pxor(marked_fields_mask, marked_fields_mask);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < jitdesc->numblocks; i++) {
|
for (unsigned int i = 0; i < jitdesc->numItrBlocks; i++) {
|
||||||
auto block = &jitdesc->blocks[i];
|
auto block = jitdesc->itrBlocks[i].memblock;
|
||||||
|
auto itrBlock = &jitdesc->itrBlocks[i];
|
||||||
|
|
||||||
if (block->isEmpty())
|
//do far prefetch
|
||||||
continue;
|
if (itrBlock->prefetchBlockId != -1) {
|
||||||
|
prefetcht0(byte_ptr[esi + (itrBlock->prefetchBlockId * 16)]);
|
||||||
movdqa(xmm0, xmm3);
|
prefetcht0(byte_ptr[edi + (itrBlock->prefetchBlockId * 16)]);
|
||||||
movdqa(xmm1, xmm4);
|
|
||||||
|
|
||||||
//prefetch next blocks
|
|
||||||
for (unsigned int j = i + 1; j < jitdesc->numblocks; j++) {
|
|
||||||
if (!jitdesc->blocks[j].isEmpty()) {
|
|
||||||
movdqu(xmm3, xmmword_ptr[esi + (j * 16)]);
|
|
||||||
movdqu(xmm4, xmmword_ptr[edi + (j * 16)]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pcmpeqb(xmm0, xmm1);
|
pcmpeqb(src_xmm[dataXmmCounter], dst_xmm[dataXmmCounter]);
|
||||||
pmovmskb(mask, xmm0);
|
pmovmskb(blockMask, src_xmm[dataXmmCounter]);
|
||||||
not_(mask);
|
not_(blockMask);
|
||||||
|
|
||||||
|
//preload next blocks
|
||||||
|
if (i + 3 < jitdesc->numItrBlocks) {
|
||||||
|
movdqu(src_xmm[dataXmmCounter], xmmword_ptr[esi + (jitdesc->itrBlocks[i + 3].memblockId * 16)]);
|
||||||
|
movdqu(dst_xmm[dataXmmCounter], xmmword_ptr[edi + (jitdesc->itrBlocks[i + 3].memblockId * 16)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
dataXmmCounter++;
|
||||||
|
if (dataXmmCounter > 2) {
|
||||||
|
dataXmmCounter -= 3;
|
||||||
|
}
|
||||||
|
|
||||||
for (unsigned int j = 0; j < block->numFields; j++) {
|
for (unsigned int j = 0; j < block->numFields; j++) {
|
||||||
auto jitField = &block->fields[j];
|
auto jitField = &block->fields[j];
|
||||||
@ -327,16 +356,16 @@ CDeltaClearMarkFieldsJIT::Result CDeltaClearMarkFieldsJIT::main(Addr src, Addr d
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
checkFieldMask(mask, jitField);
|
checkFieldMask(blockMask, jitField);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
checkFieldMask(mask, jitField);
|
checkFieldMask(blockMask, jitField);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// set bit in send mask
|
// set bit in send mask
|
||||||
movd(xmm0, edx);
|
movd(xmm_tmp, edx);
|
||||||
psllq(xmm0, jitField->field->id);
|
psllq(xmm_tmp, jitField->field->id);
|
||||||
por(marked_fields_mask, xmm0);
|
por(marked_fields_mask, xmm_tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -470,8 +499,8 @@ NOINLINE int DELTAJit_Fields_Clear_Mark_Check(unsigned char *from, unsigned char
|
|||||||
void DELTAJit_SetSendFlagBits(delta_t *pFields, int *bits, int *bytecount) {
|
void DELTAJit_SetSendFlagBits(delta_t *pFields, int *bits, int *bytecount) {
|
||||||
CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__FUNCTION__, pFields);
|
CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__FUNCTION__, pFields);
|
||||||
|
|
||||||
bits[0] = deltaJit->marked_fields_mask[0];
|
bits[0] = deltaJit->marked_fields_mask.u32[0];
|
||||||
bits[1] = deltaJit->marked_fields_mask[1];
|
bits[1] = deltaJit->marked_fields_mask.u32[1];
|
||||||
*bytecount = deltaJit->markedFieldsMaskSize;
|
*bytecount = deltaJit->markedFieldsMaskSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -479,9 +508,9 @@ void DELTAJit_SetFieldByIndex(struct delta_s *pFields, int fieldNumber) {
|
|||||||
CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__FUNCTION__, pFields);
|
CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__FUNCTION__, pFields);
|
||||||
|
|
||||||
if (fieldNumber > 31)
|
if (fieldNumber > 31)
|
||||||
deltaJit->marked_fields_mask[1] |= (1 << (fieldNumber & 0x1F));
|
deltaJit->marked_fields_mask.u32[1] |= (1 << (fieldNumber & 0x1F));
|
||||||
else
|
else
|
||||||
deltaJit->marked_fields_mask[0] |= (1 << fieldNumber);
|
deltaJit->marked_fields_mask.u32[0] |= (1 << fieldNumber);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -489,18 +518,18 @@ void DELTAJit_UnsetFieldByIndex(struct delta_s *pFields, int fieldNumber) {
|
|||||||
CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__FUNCTION__, pFields);
|
CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__FUNCTION__, pFields);
|
||||||
|
|
||||||
if (fieldNumber > 31)
|
if (fieldNumber > 31)
|
||||||
deltaJit->marked_fields_mask[1] &= ~(1 << (fieldNumber & 0x1F));
|
deltaJit->marked_fields_mask.u32[1] &= ~(1 << (fieldNumber & 0x1F));
|
||||||
else
|
else
|
||||||
deltaJit->marked_fields_mask[0] &= ~(1 << fieldNumber);
|
deltaJit->marked_fields_mask.u32[0] &= ~(1 << fieldNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
qboolean DELTAJit_IsFieldMarked(delta_t* pFields, int fieldNumber) {
|
qboolean DELTAJit_IsFieldMarked(delta_t* pFields, int fieldNumber) {
|
||||||
CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__FUNCTION__, pFields);
|
CDeltaJit* deltaJit = DELTAJit_LookupDeltaJit(__FUNCTION__, pFields);
|
||||||
|
|
||||||
if (fieldNumber > 31)
|
if (fieldNumber > 31)
|
||||||
return deltaJit->marked_fields_mask[1] & (1 << (fieldNumber & 0x1F));
|
return deltaJit->marked_fields_mask.u32[1] & (1 << (fieldNumber & 0x1F));
|
||||||
|
|
||||||
return deltaJit->marked_fields_mask[0] & (1 << fieldNumber);
|
return deltaJit->marked_fields_mask.u32[0] & (1 << fieldNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDeltaJitRegistry::Cleanup() {
|
void CDeltaJitRegistry::Cleanup() {
|
||||||
|
@ -23,7 +23,12 @@ struct deltajit_memblock_field {
|
|||||||
struct deltajit_memblock {
|
struct deltajit_memblock {
|
||||||
unsigned int numFields;
|
unsigned int numFields;
|
||||||
deltajit_memblock_field fields[24];
|
deltajit_memblock_field fields[24];
|
||||||
bool isEmpty() const;
|
};
|
||||||
|
|
||||||
|
struct deltajit_memblock_itr_t {
|
||||||
|
int memblockId;
|
||||||
|
deltajit_memblock* memblock;
|
||||||
|
int prefetchBlockId;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct deltajitdata_t {
|
struct deltajitdata_t {
|
||||||
@ -32,6 +37,9 @@ struct deltajitdata_t {
|
|||||||
|
|
||||||
unsigned int numFields;
|
unsigned int numFields;
|
||||||
deltajit_field fields[DELTAJIT_MAX_FIELDS];
|
deltajit_field fields[DELTAJIT_MAX_FIELDS];
|
||||||
|
|
||||||
|
unsigned int numItrBlocks;
|
||||||
|
deltajit_memblock_itr_t itrBlocks[DELTAJIT_MAX_BLOCKS];
|
||||||
};
|
};
|
||||||
|
|
||||||
enum deltajit_marked_count_type_t {
|
enum deltajit_marked_count_type_t {
|
||||||
@ -56,6 +64,13 @@ 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);
|
extern int DELTAJit_Fields_Clear_Mark_Check(unsigned char *from, unsigned char *to, delta_t *pFields);
|
||||||
|
@ -4156,6 +4156,8 @@ int SV_CreatePacketEntities(sv_delta_t type, client_t *client, packet_entities_t
|
|||||||
{
|
{
|
||||||
client_frame_t *fromframe = &client->frames[SV_UPDATE_MASK & client->delta_sequence];
|
client_frame_t *fromframe = &client->frames[SV_UPDATE_MASK & client->delta_sequence];
|
||||||
from = &fromframe->entities;
|
from = &fromframe->entities;
|
||||||
|
_mm_prefetch((const char*)&from->entities[0], _MM_HINT_T0);
|
||||||
|
_mm_prefetch(((const char*)&from->entities[0]) + 64, _MM_HINT_T0);
|
||||||
oldmax = from->num_entities;
|
oldmax = from->num_entities;
|
||||||
MSG_WriteByte(msg, svc_deltapacketentities);
|
MSG_WriteByte(msg, svc_deltapacketentities);
|
||||||
MSG_WriteShort(msg, to->num_entities);
|
MSG_WriteShort(msg, to->num_entities);
|
||||||
@ -4169,8 +4171,8 @@ int SV_CreatePacketEntities(sv_delta_t type, client_t *client, packet_entities_t
|
|||||||
MSG_WriteShort(msg, to->num_entities);
|
MSG_WriteShort(msg, to->num_entities);
|
||||||
}
|
}
|
||||||
|
|
||||||
newnum = 0;
|
newnum = 0; //index in to->entities
|
||||||
oldnum = 0;
|
oldnum = 0; //index in from->entities
|
||||||
MSG_StartBitWriting(msg);
|
MSG_StartBitWriting(msg);
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
@ -4201,6 +4203,8 @@ int SV_CreatePacketEntities(sv_delta_t type, client_t *client, packet_entities_t
|
|||||||
SV_SetCallback(newindex, FALSE, custom, &numbase, FALSE, 0);
|
SV_SetCallback(newindex, FALSE, custom, &numbase, FALSE, 0);
|
||||||
DELTA_WriteDelta((uint8 *)&from->entities[oldnum], (uint8 *)baseline_, FALSE, custom ? g_pcustomentitydelta : (SV_IsPlayerIndex(newindex) ? g_pplayerdelta : g_pentitydelta), &SV_InvokeCallback);
|
DELTA_WriteDelta((uint8 *)&from->entities[oldnum], (uint8 *)baseline_, FALSE, custom ? g_pcustomentitydelta : (SV_IsPlayerIndex(newindex) ? g_pplayerdelta : g_pentitydelta), &SV_InvokeCallback);
|
||||||
++oldnum;
|
++oldnum;
|
||||||
|
_mm_prefetch((const char*)&from->entities[oldnum], _MM_HINT_T0);
|
||||||
|
_mm_prefetch(((const char*)&from->entities[oldnum]) + 64, _MM_HINT_T0);
|
||||||
++newnum;
|
++newnum;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -4211,6 +4215,8 @@ int SV_CreatePacketEntities(sv_delta_t type, client_t *client, packet_entities_t
|
|||||||
{
|
{
|
||||||
SV_WriteDeltaHeader(oldindex, TRUE, FALSE, &numbase, FALSE, 0, FALSE, 0);
|
SV_WriteDeltaHeader(oldindex, TRUE, FALSE, &numbase, FALSE, 0, FALSE, 0);
|
||||||
++oldnum;
|
++oldnum;
|
||||||
|
_mm_prefetch((const char*)&from->entities[oldnum], _MM_HINT_T0);
|
||||||
|
_mm_prefetch(((const char*)&from->entities[oldnum]) + 64, _MM_HINT_T0);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -4243,6 +4249,8 @@ int SV_CreatePacketEntities(sv_delta_t type, client_t *client, packet_entities_t
|
|||||||
if (!from)
|
if (!from)
|
||||||
{
|
{
|
||||||
int offset = SV_FindBestBaseline(newnum, &baseline_, to->entities, newindex, custom);
|
int offset = SV_FindBestBaseline(newnum, &baseline_, to->entities, newindex, custom);
|
||||||
|
_mm_prefetch((const char*)baseline_, _MM_HINT_T0);
|
||||||
|
_mm_prefetch(((const char*)baseline_) + 64, _MM_HINT_T0);
|
||||||
if (offset)
|
if (offset)
|
||||||
SV_SetCallback(newindex, 0, custom, &numbase, 1, offset);
|
SV_SetCallback(newindex, 0, custom, &numbase, 1, offset);
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#ifdef _WIN32 // WINDOWS
|
#ifdef _WIN32 // WINDOWS
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
@ -26,6 +26,7 @@ struct delta_test_struct_t {
|
|||||||
uint8 b_61; //20
|
uint8 b_61; //20
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
typedef delta_test_struct_t dts_t;
|
||||||
|
|
||||||
struct delta_res_t
|
struct delta_res_t
|
||||||
{
|
{
|
||||||
@ -73,58 +74,89 @@ NOINLINE qboolean _DoMarkFields(void* src, void* dst, delta_t* delta, bool useJi
|
|||||||
return sendfields;
|
return sendfields;
|
||||||
}
|
}
|
||||||
|
|
||||||
NOINLINE bool _CheckFieldMarked(delta_t* delta, int fieldIdx, int usejit) {
|
|
||||||
if (usejit) {
|
|
||||||
return DELTAJit_IsFieldMarked(delta, fieldIdx) != 0;
|
|
||||||
} else {
|
|
||||||
return delta->pdd[fieldIdx].flags & FDT_MARK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NOINLINE void _EnsureFieldsChanged(const char* callsite, const char* action, int usejit, bool changed, delta_t* delta, ...) {
|
NOINLINE void _MarkAndEnsureCorrectResults(const char* action, delta_t* delta, void* src, void* dst, int useJit, bool changed, const char* szFields) {
|
||||||
va_list vargs;
|
delta_description_t* fields[DELTA_MAX_FIELDS];
|
||||||
va_start(vargs, delta);
|
int numFields = 0;
|
||||||
const char* fieldName = va_arg(vargs, const char*);
|
|
||||||
while (fieldName) {
|
char localFieldsStr[512];
|
||||||
delta_description_t* field = NULL;
|
strcpy(localFieldsStr, szFields);
|
||||||
int idx = 0;
|
|
||||||
for (; idx < delta->fieldCount; idx++) {
|
//parse fields
|
||||||
if (!strcmp(fieldName, delta->pdd[idx].fieldName)) {
|
int prevEnd = -1;
|
||||||
field = &delta->pdd[idx];
|
for (char* pcc = localFieldsStr; *pcc; pcc++) {
|
||||||
break;
|
if (*pcc == ' ') {
|
||||||
|
*pcc = 0;
|
||||||
|
int fIdx = DELTA_FindFieldIndex(delta, &localFieldsStr[prevEnd + 1]);
|
||||||
|
if (fIdx == -1) {
|
||||||
|
rehlds_syserror("%s: Coult not find field '%s'", &localFieldsStr[prevEnd + 1]);
|
||||||
}
|
}
|
||||||
|
fields[numFields++] = &delta->pdd[fIdx];
|
||||||
|
prevEnd = pcc - localFieldsStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field == NULL) {
|
|
||||||
rehlds_syserror("%s: %s: Could not find delta field '%s'", callsite, action, fieldName);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (field->flags & 0x80) {
|
|
||||||
rehlds_syserror("%s: %s: Field '%s' is marked as processed", callsite, action, fieldName);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (_CheckFieldMarked(delta, idx, usejit) ^ changed) {
|
|
||||||
rehlds_syserror("%s: %s: Field '%s' is expected to be marked", callsite, action, fieldName);
|
|
||||||
}
|
|
||||||
|
|
||||||
field->flags |= 0x80;
|
|
||||||
|
|
||||||
fieldName = va_arg(vargs, const char*);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < delta->fieldCount; i++) {
|
if (localFieldsStr[0] != 0) {
|
||||||
delta_description_t* field = &delta->pdd[i];
|
int fIdx = DELTA_FindFieldIndex(delta, &localFieldsStr[prevEnd + 1]);
|
||||||
if (field->flags & 0x80)
|
if (fIdx == -1) {
|
||||||
continue;
|
rehlds_syserror("%s: Coult not find field '%s'", &localFieldsStr[prevEnd + 1]);
|
||||||
|
|
||||||
if (_CheckFieldMarked(delta, i, usejit) ^ !changed) {
|
|
||||||
rehlds_syserror("%s: %s: Field '%s' is expected to be unmarked", callsite, action, field->fieldName);
|
|
||||||
}
|
}
|
||||||
|
fields[numFields++] = &delta->pdd[fIdx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//build expected mask
|
||||||
|
delta_marked_mask_t expectedMask; expectedMask.u64 = 0;
|
||||||
|
for (int i = 0; i < numFields; i++) {
|
||||||
|
delta_description_t* f = fields[i];
|
||||||
|
int fieldId = f - delta->pdd;
|
||||||
|
expectedMask.u8[fieldId >> 3] |= (1 << (fieldId & 0x7));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!changed) {
|
||||||
|
//invert mask
|
||||||
|
uint64 existingFieldsMask = 0xFFFFFFFFFFFFFFFF;
|
||||||
|
existingFieldsMask = existingFieldsMask >> (64 - delta->fieldCount);
|
||||||
|
|
||||||
|
expectedMask.u64 = ~expectedMask.u64;
|
||||||
|
expectedMask.u64 &= existingFieldsMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
//calculate expected bytecount
|
||||||
|
int expectedBytecount = 0;
|
||||||
|
for (int i = 0; i < ARRAYSIZE(expectedMask.u8); i++) {
|
||||||
|
if (expectedMask.u8[i]) {
|
||||||
|
expectedBytecount = i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//do marking
|
||||||
|
qboolean markResult = _DoMarkFields(src, dst, delta, useJit != 0);
|
||||||
|
|
||||||
|
//check marking result
|
||||||
|
if ((markResult != 0) != (expectedMask.u64 != 0)) {
|
||||||
|
rehlds_syserror("%s: DoMarkFields returned invalid value %d, expected %s", action, markResult, (expectedMask.u64 == 0) ? "0" : "!0");
|
||||||
|
}
|
||||||
|
|
||||||
|
delta_marked_mask_t returnedMask;
|
||||||
|
int returnedBytecount;
|
||||||
|
if (useJit) {
|
||||||
|
DELTAJit_SetSendFlagBits(delta, (int*)returnedMask.u32, &returnedBytecount);
|
||||||
|
} else {
|
||||||
|
DELTA_SetSendFlagBits(delta, (int*)returnedMask.u32, &returnedBytecount);
|
||||||
|
}
|
||||||
|
|
||||||
|
//check per-field marks
|
||||||
|
if (returnedMask.u64 != expectedMask.u64) {
|
||||||
|
rehlds_syserror("%s: DoMarkFields returned invalid mask %llX, expected %llX", action, returnedMask.u64, expectedMask.u64);
|
||||||
|
}
|
||||||
|
|
||||||
|
//check bytecount
|
||||||
|
if (returnedBytecount != expectedBytecount) {
|
||||||
|
rehlds_syserror("%s: DoMarkFields returned invalid bytecount %d, expected %d", action, returnedBytecount, expectedBytecount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NOINLINE void _GetBitmaskAndBytecount(delta_t* delta, int* bits, int* bytecount, int usejit) {
|
NOINLINE void _GetBitmaskAndBytecount(delta_t* delta, int* bits, int* bytecount, int usejit) {
|
||||||
if (usejit) {
|
if (usejit) {
|
||||||
DELTAJit_SetSendFlagBits(delta, bits, bytecount);
|
DELTAJit_SetSendFlagBits(delta, bits, bytecount);
|
||||||
@ -149,7 +181,7 @@ NOINLINE void _CompareDeltaResults(const char* callsite, delta_res_t* def, delta
|
|||||||
|
|
||||||
NOINLINE delta_t* _CreateTestDeltaDesc() {
|
NOINLINE delta_t* _CreateTestDeltaDesc() {
|
||||||
static delta_description_t _fields[32];
|
static delta_description_t _fields[32];
|
||||||
delta_test_struct_t d; d; // "use" d variable
|
delta_test_struct_t d; // "use" d variable
|
||||||
|
|
||||||
_InitDeltaField(&_fields[0], 0x00, DT_BYTE, "b_00", offsetof(delta_test_struct_t, b_00), 1, 8, 1.0f, 1.0f);
|
_InitDeltaField(&_fields[0], 0x00, DT_BYTE, "b_00", offsetof(delta_test_struct_t, b_00), 1, 8, 1.0f, 1.0f);
|
||||||
_InitDeltaField(&_fields[1], 0x01, DT_BYTE, "b_01", offsetof(delta_test_struct_t, b_01), 1, 8, 1.0f, 1.0f);
|
_InitDeltaField(&_fields[1], 0x01, DT_BYTE, "b_01", offsetof(delta_test_struct_t, b_01), 1, 8, 1.0f, 1.0f);
|
||||||
@ -194,266 +226,108 @@ NOINLINE delta_t* _CreateTestDeltaDesc() {
|
|||||||
return delta;
|
return delta;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST(MarkFieldsTest_Simple_Primitives, Delta, 1000) {
|
struct delta_simpletest_data_t {
|
||||||
|
const char* action;
|
||||||
|
int fill1, fill2;
|
||||||
|
bool changed;
|
||||||
|
const char* fields;
|
||||||
|
std::function<void(void)> act;
|
||||||
|
};
|
||||||
|
|
||||||
|
delta_test_struct_t dst1, dst2;
|
||||||
|
|
||||||
|
void _DeltaSimpleTest(delta_simpletest_data_t* t, delta_t* delta, int jit) {
|
||||||
|
_FillTestDelta(&dst1, t->fill1); _FillTestDelta(&dst2, t->fill2);
|
||||||
|
t->act();
|
||||||
|
_MarkAndEnsureCorrectResults(t->action, delta, &dst1, &dst2, jit, t->changed, t->fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _DeltaSimpleTests(delta_t* delta, delta_simpletest_data_t* tests, int testsCount) {
|
||||||
|
for (int usejit = 0; usejit <= 1; usejit++) {
|
||||||
|
for (int i = 0; i < testsCount; i++) {
|
||||||
|
_DeltaSimpleTest(tests + i, delta, usejit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST(MarkFieldsTest_Simple_Primitives, Delta, 1000) {
|
||||||
delta_t* delta = _CreateTestDeltaDesc();
|
delta_t* delta = _CreateTestDeltaDesc();
|
||||||
|
|
||||||
delta_test_struct_t d1;
|
delta_simpletest_data_t testdata[] = {
|
||||||
delta_test_struct_t d2;
|
{ "SimpleUnchangedAll1", 0x71, 0x71, true, "", [](){} },
|
||||||
delta_res_t res[2][10];
|
{ "SimpleUnchangedAll2", 0x71, 0x72, false, "", [](){} },
|
||||||
|
{ "Byte_0BlockCheck", 0x71, 0x71, true, "b_01", []() { dst2.b_01 = 0; } },
|
||||||
|
{ "Byte_1BlockCheck", 0x71, 0x71, true, "b_11", []() { dst2.b_11 = 0; } },
|
||||||
|
{ "Short_0BlockCheck", 0x71, 0x71, true, "s_02", []() { dst2.s_02 = 0; } },
|
||||||
|
{ "Short_1BlockCheck", 0x71, 0x71, true, "s_12", []() { dst2.s_12 = 0; } },
|
||||||
|
{ "Int_0BlockCheck", 0x71, 0x71, true, "i_04", []() { dst2.i_04 = 0; } },
|
||||||
|
{ "Int_1BlockCheck", 0x71, 0x71, true, "i_14", []() { dst2.i_14 = 0; } },
|
||||||
|
{ "Float_0BlockCheck", 0x71, 0x71, true, "f_08", []() { dst2.f_08 = 0; } },
|
||||||
|
{ "Float_1BlockCheck", 0x71, 0x71, true, "f_18", []() { dst2.f_18 = 0; } },
|
||||||
|
};
|
||||||
|
_DeltaSimpleTests(delta, testdata, ARRAYSIZE(testdata));
|
||||||
|
|
||||||
memset(res[0], 0xCC, sizeof(res) / 2);
|
|
||||||
memset(res[1], 0xDD, sizeof(res) / 2);
|
|
||||||
|
|
||||||
for (int usejit = 0; usejit <= 1; usejit++) {
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
|
|
||||||
res[usejit][0].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][0].bits, &res[usejit][0].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "SimpleUnchangedAll", usejit, true, delta, NULL);
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x72);
|
|
||||||
res[usejit][1].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][1].bits, &res[usejit][1].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "SimpleUnchangedAll", usejit, false, delta, NULL);
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
|
|
||||||
d2.b_01 = 0;
|
|
||||||
res[usejit][2].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][2].bits, &res[usejit][2].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "Byte_0BlockCheck", usejit, true, delta, "b_01", NULL);
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
|
|
||||||
d2.b_11 = 0;
|
|
||||||
res[usejit][3].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][3].bits, &res[usejit][3].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "Byte_1BlockCheck", usejit, true, delta, "b_11", NULL);
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
|
|
||||||
d2.s_02 = 0;
|
|
||||||
res[usejit][4].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][4].bits, &res[usejit][4].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "Short_0BlockCheck", usejit, true, delta, "s_02", NULL);
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
|
|
||||||
d2.s_12 = 0;
|
|
||||||
res[usejit][5].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][5].bits, &res[usejit][5].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "Short_1BlockCheck", usejit, true, delta, "s_12", NULL);
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
|
|
||||||
d2.i_04 = 0;
|
|
||||||
res[usejit][6].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][6].bits, &res[usejit][6].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "Int_0BlockCheck", usejit, true, delta, "i_04", NULL);
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
|
|
||||||
d2.i_14 = 0;
|
|
||||||
res[usejit][7].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][7].bits, &res[usejit][7].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "Int_1BlockCheck", usejit, true, delta, "i_14", NULL);
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
|
|
||||||
d2.f_08 = 0;
|
|
||||||
res[usejit][8].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][8].bits, &res[usejit][8].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "Float_0BlockCheck", usejit, true, delta, "f_08", NULL);
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
|
|
||||||
d2.f_18 = 0;
|
|
||||||
res[usejit][9].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][9].bits, &res[usejit][9].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "Float_0BlockCheck", usejit, true, delta, "f_18", NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
_CompareDeltaResults(__FUNCTION__, res[0], res[1], 10);
|
|
||||||
SV_Shutdown();
|
SV_Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MarkFieldsTest_InterBlock, Delta, 1000) {
|
TEST(MarkFieldsTest_InterBlock, Delta, 1000) {
|
||||||
|
|
||||||
delta_t* delta = _CreateTestDeltaDesc();
|
delta_t* delta = _CreateTestDeltaDesc();
|
||||||
|
|
||||||
delta_test_struct_t d1;
|
delta_simpletest_data_t testdata[] = {
|
||||||
delta_test_struct_t d2;
|
{ "Interblock1_guards", 0x71, 0x71, true, "b_4D b_52", []() { dst2.b_4D = dst2.b_52 = 0; } },
|
||||||
delta_res_t res[2][14];
|
{ "Interblock1_guards_and_val", 0x71, 0x71, true, "b_4D b_52 i_4E", []() { dst2.b_4D = dst2.b_52 = 0; dst2.i_4E = 0; } },
|
||||||
|
{ "Interblock1_val", 0x71, 0x71, true, "i_4E", []() { dst2.i_4E = 0; } },
|
||||||
|
{ "Interblock1_val_0b", 0x71, 0x71, true, "i_4E", []() { dst2.i_4E &= 0xFFFFFF00; } },
|
||||||
|
{ "Interblock1_val_1b", 0x71, 0x71, true, "i_4E", []() { dst2.i_4E &= 0xFFFF00FF; } },
|
||||||
|
{ "Interblock1_val_2b", 0x71, 0x71, true, "i_4E", []() { dst2.i_4E &= 0xFF00FFFF; } },
|
||||||
|
{ "Interblock1_val_3b", 0x71, 0x71, true, "i_4E", []() { dst2.i_4E &= 0x00FFFFFF; } },
|
||||||
|
|
||||||
memset(res[0], 0xCC, sizeof(res) / 2);
|
{ "Interblock2_guards", 0x71, 0x71, true, "b_5C b_61", []() { dst2.b_5C = dst2.b_61 = 0; } },
|
||||||
memset(res[1], 0xDD, sizeof(res) / 2);
|
{ "Interblock2_guards_and_val", 0x71, 0x71, true, "b_5C b_61 i_5D", []() { dst2.b_5C = dst2.b_61 = 0; dst2.i_5D = 0; } },
|
||||||
|
{ "Interblock2_val", 0x71, 0x71, true, "i_5D", []() { dst2.i_5D = 0; } },
|
||||||
|
{ "Interblock2_val_0b", 0x71, 0x71, true, "i_5D", []() { dst2.i_5D &= 0xFFFFFF00; } },
|
||||||
|
{ "Interblock2_val_1b", 0x71, 0x71, true, "i_5D", []() { dst2.i_5D &= 0xFFFF00FF; } },
|
||||||
|
{ "Interblock2_val_2b", 0x71, 0x71, true, "i_5D", []() { dst2.i_5D &= 0xFF00FFFF; } },
|
||||||
|
{ "Interblock2_val_3b", 0x71, 0x71, true, "i_5D", []() { dst2.i_5D &= 0x00FFFFFF; } },
|
||||||
|
};
|
||||||
|
_DeltaSimpleTests(delta, testdata, ARRAYSIZE(testdata));
|
||||||
|
|
||||||
for (int usejit = 0; usejit <= 1; usejit++) {
|
|
||||||
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
|
|
||||||
d2.b_4D = d2.b_52 = 0;
|
|
||||||
res[usejit][0].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][0].bits, &res[usejit][0].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "Interblock1_guards", usejit, true, delta, "b_4D", "b_52", NULL);
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
|
|
||||||
d2.b_4D = d2.b_52 = 0;
|
|
||||||
d2.i_4E = 0;
|
|
||||||
res[usejit][1].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][1].bits, &res[usejit][1].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "Interblock1_guards_and_val", usejit, true, delta, "b_4D", "b_52", "i_4E", NULL);
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
|
|
||||||
d2.i_4E = 0;
|
|
||||||
res[usejit][2].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][2].bits, &res[usejit][2].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "Interblock1_val", usejit, true, delta, "i_4E", NULL);
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
|
|
||||||
d2.i_4E &= 0xFFFFFF00;
|
|
||||||
res[usejit][3].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][3].bits, &res[usejit][3].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "Interblock1_val_0b", usejit, true, delta, "i_4E", NULL);
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
|
|
||||||
d2.i_4E &= 0xFFFF00FF;
|
|
||||||
res[usejit][4].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][4].bits, &res[usejit][4].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "Interblock1_val_1b", usejit, true, delta, "i_4E", NULL);
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
|
|
||||||
d2.i_4E &= 0xFF00FFFF;
|
|
||||||
res[usejit][5].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][5].bits, &res[usejit][5].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "Interblock1_val_2b", usejit, true, delta, "i_4E", NULL);
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
|
|
||||||
d2.i_4E &= 0x00FFFFFF;
|
|
||||||
res[usejit][6].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][6].bits, &res[usejit][6].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "Interblock1_val_3b", usejit, true, delta, "i_4E", NULL);
|
|
||||||
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
|
|
||||||
d2.b_5C = d2.b_61 = 0;
|
|
||||||
res[usejit][7].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][7].bits, &res[usejit][7].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "Interblock2_guards", usejit, true, delta, "b_5C", "b_61", NULL);
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
|
|
||||||
d2.b_5C = d2.b_61 = 0;
|
|
||||||
d2.i_5D = 0;
|
|
||||||
res[usejit][8].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][8].bits, &res[usejit][8].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "Interblock2_guards_and_val", usejit, true, delta, "b_5C", "b_61", "i_5D", NULL);
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
|
|
||||||
d2.i_5D = 0;
|
|
||||||
res[usejit][9].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][9].bits, &res[usejit][9].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "Interblock2_val", usejit, true, delta, "i_5D", NULL);
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
|
|
||||||
d2.i_5D &= 0xFFFFFF00;
|
|
||||||
res[usejit][10].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][10].bits, &res[usejit][10].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "Interblock2_val_0b", usejit, true, delta, "i_5D", NULL);
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
|
|
||||||
d2.i_5D &= 0xFFFF00FF;
|
|
||||||
res[usejit][11].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][11].bits, &res[usejit][11].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "Interblock2_val_1b", usejit, true, delta, "i_5D", NULL);
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
|
|
||||||
d2.i_5D &= 0xFF00FFFF;
|
|
||||||
res[usejit][12].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][12].bits, &res[usejit][12].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "Interblock2_val_2b", usejit, true, delta, "i_5D", NULL);
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 0x71); _FillTestDelta(&d2, 0x71);
|
|
||||||
d2.i_5D &= 0x00FFFFFF;
|
|
||||||
res[usejit][13].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][13].bits, &res[usejit][13].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "Interblock2_val_3b", usejit, true, delta, "i_5D", NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
_CompareDeltaResults(__FUNCTION__, res[0], res[1], 14);
|
|
||||||
SV_Shutdown();
|
SV_Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MarkFieldsTest_Strings, Delta, 1000) {
|
TEST(MarkFieldsTest_Strings, Delta, 1000) {
|
||||||
|
|
||||||
delta_t* delta = _CreateTestDeltaDesc();
|
delta_t* delta = _CreateTestDeltaDesc();
|
||||||
|
|
||||||
delta_test_struct_t d1;
|
delta_simpletest_data_t testdata[] = {
|
||||||
delta_test_struct_t d2;
|
{ "Str_empty", 'c', 'c', true, "s_24", []() { dst2.s_24[0] = 0; } },
|
||||||
delta_res_t res[2][4];
|
{ "Str_empty2", 'c', 'c', true, "s_24", []() { dst1.s_24[0] = 0; } },
|
||||||
|
{ "Str_both_empty_with_garbage", 'c', 'c', true, "", []() {
|
||||||
|
dst1.s_24[0] = 0; dst2.s_24[0] = 0;
|
||||||
|
dst1.s_24[1] = 'd'; dst2.s_24[1] = 'e';
|
||||||
|
}},
|
||||||
|
{ "Str_case_check", 'c', 'c', true, "", []() { dst1.s_24[0] = 'C'; } },
|
||||||
|
};
|
||||||
|
_DeltaSimpleTests(delta, testdata, ARRAYSIZE(testdata));
|
||||||
|
|
||||||
memset(res[0], 0xCC, sizeof(res) / 2);
|
|
||||||
memset(res[1], 0xDD, sizeof(res) / 2);
|
|
||||||
|
|
||||||
for (int usejit = 0; usejit <= 1; usejit++) {
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 'c'); _FillTestDelta(&d2, 'c');
|
|
||||||
d2.s_24[0] = 0;
|
|
||||||
res[usejit][0].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][0].bits, &res[usejit][0].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "Str_empty", usejit, true, delta, "s_24", NULL);
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 'c'); _FillTestDelta(&d2, 'c');
|
|
||||||
d1.s_24[0] = 0;
|
|
||||||
res[usejit][1].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][1].bits, &res[usejit][1].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "Str_empty2", usejit, true, delta, "s_24", NULL);
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 'c'); _FillTestDelta(&d2, 'c');
|
|
||||||
d1.s_24[0] = d2.s_24[0] = 0;
|
|
||||||
d1.s_24[1] = 'd'; d2.s_24[1] = 'e';
|
|
||||||
res[usejit][2].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][2].bits, &res[usejit][2].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "Str_both_empty_with_garbage", usejit, true, delta, NULL);
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 'c'); _FillTestDelta(&d2, 'c');
|
|
||||||
d1.s_24[1] = 'C';
|
|
||||||
res[usejit][3].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][3].bits, &res[usejit][3].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "Str_case_check", usejit, true, delta, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
_CompareDeltaResults(__FUNCTION__, res[0], res[1], 4);
|
|
||||||
SV_Shutdown();
|
SV_Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MarkFieldsTest_TimeWindow, Delta, 1000) {
|
TEST(MarkFieldsTest_TimeWindow, Delta, 1000) {
|
||||||
#ifdef REHLDS_FIXES
|
#ifdef REHLDS_FIXES
|
||||||
bool rehds_fixes = true;
|
bool rehlds_fixes = true;
|
||||||
#else
|
#else
|
||||||
bool rehds_fixes = false;
|
bool rehlds_fixes = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
delta_t* delta = _CreateTestDeltaDesc();
|
delta_t* delta = _CreateTestDeltaDesc();
|
||||||
|
|
||||||
delta_test_struct_t d1;
|
delta_simpletest_data_t testdata[] = {
|
||||||
delta_test_struct_t d2;
|
{ "TimeWindow_Below_Precision", 'c', 'c', true, (rehlds_fixes ? "w8_1C" : ""), []() { dst2.w8_1C = 0.001f; dst1.w8_1C = 0.0011f; } },
|
||||||
delta_res_t res[2][3];
|
{ "TimeWindow_Above_Precision1", 'c', 'c', true, (rehlds_fixes ? "w8_1C" : ""), []() { dst2.w8_1C = 0.1f; dst1.w8_1C = 0.11f; } }, //precision check, 0.11f is actually 0.10999
|
||||||
|
{ "TimeWindow_Above_Precision2", 'c', 'c', true, "w8_1C", []() { dst2.w8_1C = 0.1f; dst1.w8_1C = 0.12f; } },
|
||||||
|
};
|
||||||
|
_DeltaSimpleTests(delta, testdata, ARRAYSIZE(testdata));
|
||||||
|
|
||||||
memset(res[0], 0xCC, sizeof(res) / 2);
|
|
||||||
memset(res[1], 0xDD, sizeof(res) / 2);
|
|
||||||
|
|
||||||
for (int usejit = 0; usejit <= 1; usejit++) {
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 'c'); _FillTestDelta(&d2, 'c');
|
|
||||||
d2.w8_1C = 0.001f; d1.w8_1C = 0.0011f;
|
|
||||||
res[usejit][0].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][0].bits, &res[usejit][0].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "TimeWindow_Below_Precision", usejit, true, delta, rehds_fixes ? "w8_1C" : NULL, NULL);
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 'c'); _FillTestDelta(&d2, 'c');
|
|
||||||
d2.w8_1C = 0.1f; d1.w8_1C = 0.11f; //precision check, 0.11f is actually 0.10999
|
|
||||||
res[usejit][1].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][1].bits, &res[usejit][1].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "TimeWindow_Above_Precision1", usejit, true, delta, rehds_fixes ? "w8_1C" : NULL, NULL);
|
|
||||||
|
|
||||||
_FillTestDelta(&d1, 'c'); _FillTestDelta(&d2, 'c');
|
|
||||||
d2.w8_1C = 0.1f; d1.w8_1C = 0.12f;
|
|
||||||
res[usejit][2].sendfields = _DoMarkFields(&d1, &d2, delta, usejit != 0);
|
|
||||||
_GetBitmaskAndBytecount(delta, res[usejit][2].bits, &res[usejit][2].bytecount, usejit);
|
|
||||||
_EnsureFieldsChanged(__FUNCTION__, "TimeWindow_Above_Precision2", usejit, true, delta, "w8_1C", NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
_CompareDeltaResults(__FUNCTION__, res[0], res[1], 3);
|
|
||||||
SV_Shutdown();
|
SV_Shutdown();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user