diff --git a/renderdoc/common/common.cpp b/renderdoc/common/common.cpp index 59e5f99ef..c2520208c 100644 --- a/renderdoc/common/common.cpp +++ b/renderdoc/common/common.cpp @@ -56,6 +56,144 @@ void rdcassert(const char *condition, const char *file, unsigned int line, const rdclog_int(RDCLog_Error, file, line, "Assertion failed: '%hs'", condition, file, line); } +static __m128 zero = {0}; + +// assumes a and b both point to 16-byte aligned 16-byte chunks of memory. +// Returns if they're equal or different +bool Vec16NotEqual(void *a, void *b) +{ + // disabled SSE version as it's acting dodgy +#if 0 + __m128 avec = _mm_load_ps(aflt); + __m128 bvec = _mm_load_ps(bflt); + + __m128 diff = _mm_xor_ps(avec, bvec); + + __m128 eq = _mm_cmpeq_ps(diff, zero); + int mask = _mm_movemask_ps(eq); + int signMask = _mm_movemask_ps(diff); + + // first check ensures that diff is floatequal to zero (ie. avec bitwise equal to bvec). + // HOWEVER -0 is floatequal to 0, so we ensure no sign bits are set on diff + if((mask^0xf) || signMask != 0) + { + return true; + } + + return false; +#elif defined(WIN64) + uint64_t *a64 = (uint64_t *)a; + uint64_t *b64 = (uint64_t *)b; + + return a64[0] != b64[0] || + a64[1] != b64[1]; +#else + uint32_t *a32 = (uint32_t *)a; + uint32_t *b32 = (uint32_t *)b; + + return a32[0] != b32[0] || + a32[1] != b32[1] || + a32[2] != b32[2] || + a32[3] != b32[3]; +#endif +} + +bool FindDiffRange(void *a, void *b, size_t bufSize, size_t &diffStart, size_t &diffEnd) +{ + RDCASSERT(((unsigned long)a)%16 == 0); + RDCASSERT(((unsigned long)b)%16 == 0); + + diffStart = bufSize+1; + diffEnd = 0; + + size_t alignedSize = bufSize&(~0xf); + size_t numVecs = alignedSize/16; + + size_t offs = 0; + + float *aflt = (float *)a; + float *bflt = (float *)b; + + // init a vector to 0 + __m128 zero = {0}; + + // sweep to find the start of differences + for(size_t v=0; v < numVecs; v++) + { + if(Vec16NotEqual(aflt, bflt)) + { + diffStart = offs; + break; + } + + aflt+=4;bflt+=4;offs+=4*sizeof(float); + } + + // make sure we're byte-accurate, to comply with WRITE_NO_OVERWRITE + while(diffStart < bufSize && *((byte *)a + diffStart) == *((byte *)b + diffStart)) diffStart++; + + // do we have some unaligned bytes at the end of the buffer? + if(bufSize > alignedSize) + { + size_t numBytes = alignedSize-bufSize; + + // if we haven't even found a start, check in these bytes + if(diffStart > bufSize) + { + offs = bufSize; + + for(size_t by=0; by < numBytes; by++) + { + if(*((byte *)a + alignedSize + by) != *((byte *)b + alignedSize + by)) + { + diffStart = offs; + break; + } + + offs++; + } + } + + // sweep from the last byte to find the end + for(size_t by=0; by < numBytes; by++) + { + if(*((byte *)a + bufSize-1 - by) != *((byte *)b + bufSize-1 - by)) + { + diffEnd = bufSize-by; + break; + } + } + } + + // if we haven't found a start, or we've found a start AND and end, + // then we're done. + if(diffStart > bufSize || diffEnd > 0) + return diffStart < bufSize; + + offs = alignedSize; + + // sweep from the last __m128 + aflt = (float *)a + offs/sizeof(float) - 4; + bflt = (float *)b + offs/sizeof(float) - 4; + + for(size_t v=0; v < numVecs; v++) + { + if(Vec16NotEqual(aflt, bflt)) + { + diffEnd = offs; + break; + } + + aflt-=4;bflt-=4;offs-=16; + } + + // make sure we're byte-accurate, to comply with WRITE_NO_OVERWRITE + while(diffEnd > 0 && *((byte *)a + diffEnd - 1) == *((byte *)b + diffEnd - 1)) diffEnd--; + + // if we found a start then we necessarily found an end + return diffStart < bufSize; +} + static wstring &logfile() { static wstring fn; diff --git a/renderdoc/common/common.h b/renderdoc/common/common.h index 26c23cd5e..848e52bb0 100644 --- a/renderdoc/common/common.h +++ b/renderdoc/common/common.h @@ -84,6 +84,8 @@ inline T AlignUp16(T x) { return (x+0xf) & (~0xf); } #define MAKE_FOURCC(a, b, c, d) (((uint32_t)(d) << 24) | ((uint32_t)(c) << 16) | ((uint32_t)(b) << 8) | (uint32_t)(a)) +bool FindDiffRange(void *a, void *b, size_t bufSize, size_t &diffStart, size_t &diffEnd); + ///////////////////////////////////////////////// // Debugging features diff --git a/renderdoc/driver/d3d11/d3d11_context_wrap.cpp b/renderdoc/driver/d3d11/d3d11_context_wrap.cpp index 905121e38..ae9cb4ec9 100644 --- a/renderdoc/driver/d3d11/d3d11_context_wrap.cpp +++ b/renderdoc/driver/d3d11/d3d11_context_wrap.cpp @@ -6048,144 +6048,6 @@ void MapIntercept::CopyToD3D(size_t RangeStart, size_t RangeEnd) } } -static __m128 zero = {0}; - -// assumes a and b both point to 16-byte aligned 16-byte chunks of memory. -// Returns if they're equal or different -bool Vec16NotEqual(void *a, void *b) -{ - // disabled SSE version as it's acting dodgy -#if 0 - __m128 avec = _mm_load_ps(aflt); - __m128 bvec = _mm_load_ps(bflt); - - __m128 diff = _mm_xor_ps(avec, bvec); - - __m128 eq = _mm_cmpeq_ps(diff, zero); - int mask = _mm_movemask_ps(eq); - int signMask = _mm_movemask_ps(diff); - - // first check ensures that diff is floatequal to zero (ie. avec bitwise equal to bvec). - // HOWEVER -0 is floatequal to 0, so we ensure no sign bits are set on diff - if((mask^0xf) || signMask != 0) - { - return true; - } - - return false; -#elif defined(WIN64) - uint64_t *a64 = (uint64_t *)a; - uint64_t *b64 = (uint64_t *)b; - - return a64[0] != b64[0] || - a64[1] != b64[1]; -#else - uint32_t *a32 = (uint32_t *)a; - uint32_t *b32 = (uint32_t *)b; - - return a32[0] != b32[0] || - a32[1] != b32[1] || - a32[2] != b32[2] || - a32[3] != b32[3]; -#endif -} - -bool FindDiffRange(void *a, void *b, size_t bufSize, size_t &diffStart, size_t &diffEnd) -{ - RDCASSERT(((unsigned long)a)%16 == 0); - RDCASSERT(((unsigned long)b)%16 == 0); - - diffStart = bufSize+1; - diffEnd = 0; - - size_t alignedSize = bufSize&(~0xf); - size_t numVecs = alignedSize/16; - - size_t offs = 0; - - float *aflt = (float *)a; - float *bflt = (float *)b; - - // init a vector to 0 - __m128 zero = {0}; - - // sweep to find the start of differences - for(size_t v=0; v < numVecs; v++) - { - if(Vec16NotEqual(aflt, bflt)) - { - diffStart = offs; - break; - } - - aflt+=4;bflt+=4;offs+=4*sizeof(float); - } - - // make sure we're byte-accurate, to comply with WRITE_NO_OVERWRITE - while(diffStart < bufSize && *((byte *)a + diffStart) == *((byte *)b + diffStart)) diffStart++; - - // do we have some unaligned bytes at the end of the buffer? - if(bufSize > alignedSize) - { - size_t numBytes = alignedSize-bufSize; - - // if we haven't even found a start, check in these bytes - if(diffStart > bufSize) - { - offs = bufSize; - - for(size_t by=0; by < numBytes; by++) - { - if(*((byte *)a + alignedSize + by) != *((byte *)b + alignedSize + by)) - { - diffStart = offs; - break; - } - - offs++; - } - } - - // sweep from the last byte to find the end - for(size_t by=0; by < numBytes; by++) - { - if(*((byte *)a + bufSize-1 - by) != *((byte *)b + bufSize-1 - by)) - { - diffEnd = bufSize-by; - break; - } - } - } - - // if we haven't found a start, or we've found a start AND and end, - // then we're done. - if(diffStart > bufSize || diffEnd > 0) - return diffStart < bufSize; - - offs = alignedSize; - - // sweep from the last __m128 - aflt = (float *)a + offs/sizeof(float) - 4; - bflt = (float *)b + offs/sizeof(float) - 4; - - for(size_t v=0; v < numVecs; v++) - { - if(Vec16NotEqual(aflt, bflt)) - { - diffEnd = offs; - break; - } - - aflt-=4;bflt-=4;offs-=16; - } - - // make sure we're byte-accurate, to comply with WRITE_NO_OVERWRITE - while(diffEnd > 0 && *((byte *)a + diffEnd - 1) == *((byte *)b + diffEnd - 1)) diffEnd--; - - // if we found a start then we necessarily found an end - return diffStart < bufSize; -} - bool WrappedID3D11DeviceContext::Serialise_Map(ID3D11Resource *pResource, UINT Subresource, D3D11_MAP MapType, UINT MapFlags, D3D11_MAPPED_SUBRESOURCE *pMappedResource) { D3D11_MAPPED_SUBRESOURCE mappedResource = D3D11_MAPPED_SUBRESOURCE();