apitrace: Changes to 'upstream'
0 files changed
New commits:
commit b2754af2a0257ef8a7649fd76b7c0bc034e52c89
Author: Jose Fonseca <jfonseca@vmware.com>
Date: Mon Jun 19 14:22:55 2017 +0100
d3dretrace: Swizzle RowPitch in ID3D10*::Map.
A bit of an hack, but still better than no swizlling what so ever.
diff --git a/retrace/dxgiretrace.py b/retrace/dxgiretrace.py
index 789cefe..8432994 100755
--- a/retrace/dxgiretrace.py
+++ b/retrace/dxgiretrace.py
@@ -361,7 +361,6 @@ class D3DRetracer(Retracer):
print ' _normalizeMap(pResource, pMappedResource);'
else:
print ' _pbData = _MapDesc.pData;'
- self.checkPitchMismatch(method)
print ' } else {'
print ' return;'
print ' }'
@@ -397,23 +396,43 @@ class D3DRetracer(Retracer):
Retracer.retraceInterfaceMethodBody(self, interface, method)
# Add pitch swizzling information to the region
- if interface.name.startswith('ID3D11DeviceContext') and method.name == 'Map':
- outArg = method.getArgByName('pMappedResource')
- print r' if (_pbData && pMappedResource->RowPitch != 0) {'
+ if method.name == 'Map' and interface.name not in ('ID3D10Buffer', 'ID3D10Texture1D'):
+ if interface.name.startswith('ID3D11DeviceContext'):
+ outArg = method.getArgByName('pMappedResource')
+ memberNames = ('pData', 'RowPitch', 'DepthPitch')
+ elif interface.name.startswith('ID3D10'):
+ outArg = method.args[-1]
+ memberNames = ('pData', 'RowPitch', 'DepthPitch')
+ elif interface.name == 'IDXGISurface':
+ outArg = method.getArgByName('pLockedRect')
+ memberNames = ('pBits', 'Pitch', None)
+ else:
+ raise NotImplementedError
+ struct = outArg.type.type
+ dataMemberName, rowPitchMemberName, depthPitchMemberName = memberNames
+ dataMemberIndex = struct.getMemberByName(dataMemberName)
+ rowPitchMemberIndex = struct.getMemberByName(rowPitchMemberName)
+ print r' if (_pbData && %s->%s != 0) {' % (outArg.name, rowPitchMemberName)
print r' const trace::Array *_%s = call.arg(%u).toArray();' % (outArg.name, outArg.index)
print r' if (%s) {' % outArg.name
print r' const trace::Struct *_struct = _%s->values[0]->toStruct();' % (outArg.name)
print r' if (_struct) {'
- struct = outArg.type.type
- print r' unsigned long long traceAddress = _struct->members[%u]->toUIntPtr();' % struct.getMemberByName('pData')
- print r' int traceRowPitch = _struct->members[%u]->toSInt();' % struct.getMemberByName('RowPitch')
- print r' int realRowPitch = pMappedResource->RowPitch;'
+ print r' unsigned long long traceAddress = _struct->members[%u]->toUIntPtr();' % dataMemberIndex
+ print r' int traceRowPitch = _struct->members[%u]->toSInt();' % rowPitchMemberIndex
+ print r' int realRowPitch = %s->%s;' % (outArg.name, rowPitchMemberName)
print r' if (realRowPitch && traceRowPitch != realRowPitch) {'
print r' retrace::setRegionPitch(traceAddress, 2, traceRowPitch, realRowPitch);'
- print r' if (pMappedResource->DepthPitch) {'
- print r' retrace::checkMismatch(call, "DepthPitch", _struct->members[%u], pMappedResource->DepthPitch);' % (struct.getMemberByName('DepthPitch'))
- print r' }'
print r' }'
+ try:
+ depthPitchMemberIndex = struct.getMemberByName(depthPitchMemberName)
+ except ValueError:
+ assert len(struct.members) < 3
+ pass
+ else:
+ assert depthPitchMemberName == 'DepthPitch'
+ print r' if (%s->DepthPitch) {' % outArg.name
+ print r' retrace::checkMismatch(call, "DepthPitch", _struct->members[%u], %s->DepthPitch);' % (struct.getMemberByName('DepthPitch'), outArg.name)
+ print r' }'
print r' }'
print r' }'
print r' }'
commit 37f769f2a85e690913390ede3ae202e1a94deb65
Author: Jose Fonseca <jfonseca@vmware.com>
Date: Fri Jun 16 17:57:39 2017 +0100
d3dretrace: Swizzle RowPitch in ID3D11DeviceContext::Map.
diff --git a/retrace/dxgiretrace.py b/retrace/dxgiretrace.py
index 97d2b59..789cefe 100755
--- a/retrace/dxgiretrace.py
+++ b/retrace/dxgiretrace.py
@@ -359,7 +359,6 @@ class D3DRetracer(Retracer):
# Prevent false warnings on 1D and 2D resources, since the
# pitches are often junk there...
print ' _normalizeMap(pResource, pMappedResource);'
- self.checkPitchMismatch(method)
else:
print ' _pbData = _MapDesc.pData;'
self.checkPitchMismatch(method)
@@ -394,6 +393,32 @@ class D3DRetracer(Retracer):
print r' (*%s)->SetPrivateData(d3dstate::GUID_D3DSTATE, BytecodeLength, pShaderBytecode);' % ppShader.name
print r' }'
+ def retraceInterfaceMethodBody(self, interface, method):
+ Retracer.retraceInterfaceMethodBody(self, interface, method)
+
+ # Add pitch swizzling information to the region
+ if interface.name.startswith('ID3D11DeviceContext') and method.name == 'Map':
+ outArg = method.getArgByName('pMappedResource')
+ print r' if (_pbData && pMappedResource->RowPitch != 0) {'
+ print r' const trace::Array *_%s = call.arg(%u).toArray();' % (outArg.name, outArg.index)
+ print r' if (%s) {' % outArg.name
+ print r' const trace::Struct *_struct = _%s->values[0]->toStruct();' % (outArg.name)
+ print r' if (_struct) {'
+ struct = outArg.type.type
+ print r' unsigned long long traceAddress = _struct->members[%u]->toUIntPtr();' % struct.getMemberByName('pData')
+ print r' int traceRowPitch = _struct->members[%u]->toSInt();' % struct.getMemberByName('RowPitch')
+ print r' int realRowPitch = pMappedResource->RowPitch;'
+ print r' if (realRowPitch && traceRowPitch != realRowPitch) {'
+ print r' retrace::setRegionPitch(traceAddress, 2, traceRowPitch, realRowPitch);'
+ print r' if (pMappedResource->DepthPitch) {'
+ print r' retrace::checkMismatch(call, "DepthPitch", _struct->members[%u], pMappedResource->DepthPitch);' % (struct.getMemberByName('DepthPitch'))
+ print r' }'
+ print r' }'
+ print r' }'
+ print r' }'
+ print r' }'
+
+
def extractArg(self, function, arg, arg_type, lvalue, rvalue):
# Set object names
if function.name == 'SetPrivateData' and arg.name == 'pData':
diff --git a/retrace/retrace_stdc.cpp b/retrace/retrace_stdc.cpp
index 2a57ef0..a2ce3f3 100644
--- a/retrace/retrace_stdc.cpp
+++ b/retrace/retrace_stdc.cpp
@@ -52,33 +52,68 @@ static void retrace_malloc(trace::Call &call) {
}
-static void retrace_memcpy(trace::Call &call) {
- void * destPtr;
- size_t destLen;
- retrace::toRange(call.arg(0), destPtr, destLen);
+static void
+retrace_memcpy(trace::Call &call)
+{
+ retrace::Range destRange;
+ retrace::toRange(call.arg(0), destRange);
- void * srcPtr;
- size_t srcLen;
- retrace::toRange(call.arg(1), srcPtr, srcLen);
+ retrace::Range srcRange;
+ retrace::toRange(call.arg(1), srcRange);
size_t n = call.arg(2).toUInt();
- if (!destPtr || !srcPtr || !n) {
+ if (!destRange.ptr || !srcRange.ptr || !n) {
return;
}
- if (n > destLen) {
- retrace::warning(call) << "dest buffer overflow of " << n - destLen << " bytes\n";
+ // We don't support sources with swizzled pitches
+ assert(srcRange.dims == 0);
+
+ assert(destRange.dims <= 2);
+ if (destRange.dims == 2 &&
+ destRange.tracePitch != destRange.realPitch) {
+ int srcPitch = destRange.tracePitch;
+ int destPitch = destRange.realPitch;
+
+ if (0) {
+ retrace::warning(call) << "swizzling pitch from " << srcPitch << " to " << destPitch << "\n";
+ }
+
+ int destOffset = 0;
+ int srcOffset = 0;
+ int width = std::min(destPitch, srcPitch);
+ while (destOffset + width <= destRange.len &&
+ srcOffset + width <= srcRange.len) {
+ memcpy((char *)destRange.ptr + destOffset,
+ (char *)srcRange.ptr + srcOffset, width);
+ destOffset += destPitch;
+ srcOffset += srcPitch;
+ }
+
+ if (destOffset < destRange.len &&
+ srcOffset < srcRange.len) {
+ width = std::min(destRange.len - destOffset, srcRange.len - srcOffset);
+ memcpy((char *)destRange.ptr + destOffset,
+ (char *)srcRange.ptr + srcOffset, width);
+ }
+
+ return;
+ }
+
+
+ if (n > destRange.len) {
+ retrace::warning(call) << "dest buffer overflow of " << n - destRange.len << " bytes\n";
}
- if (n > srcLen) {
- retrace::warning(call) << "src buffer overflow of " << n - srcLen << " bytes\n";
+ if (n > srcRange.len) {
+ retrace::warning(call) << "src buffer overflow of " << n - srcRange.len << " bytes\n";
}
- n = std::min(n, destLen);
- n = std::min(n, srcLen);
+ n = std::min(n, destRange.len);
+ n = std::min(n, srcRange.len);
- memcpy(destPtr, srcPtr, n);
+ memcpy(destRange.ptr, srcRange.ptr, n);
}
diff --git a/retrace/retrace_swizzle.cpp b/retrace/retrace_swizzle.cpp
index c308334..e27af7e 100644
--- a/retrace/retrace_swizzle.cpp
+++ b/retrace/retrace_swizzle.cpp
@@ -37,8 +37,11 @@ namespace retrace {
struct Region
{
- void *buffer;
- unsigned long long size;
+ void *buffer = nullptr;
+ unsigned long long size = 0;
+ unsigned dimensions = 0;
+ int tracePitch = 0;
+ int realPitch = 0;
};
typedef std::map<unsigned long long, Region> RegionMap;
@@ -114,7 +117,7 @@ addRegion(trace::Call &call, unsigned long long address, void *buffer, unsigned
if (!address) {
// Ignore NULL pointer
- assert(!buffer);
+ assert(buffer == nullptr);
return;
}
@@ -168,6 +171,19 @@ lookupRegion(unsigned long long address) {
}
void
+setRegionPitch(unsigned long long address, unsigned dimensions, int tracePitch, int realPitch) {
+ RegionMap::iterator it = lookupRegion(address);
+ if (it != regionMap.end()) {
+ Region ®ion = it->second;
+ region.dimensions = dimensions;
+ region.tracePitch = tracePitch;
+ region.realPitch = realPitch;
+ } else {
+ assert(0);
+ }
+}
+
+void
delRegion(unsigned long long address) {
RegionMap::iterator it = lookupRegion(address);
if (it != regionMap.end()) {
@@ -190,14 +206,18 @@ delRegionByPointer(void *ptr) {
}
static void
-lookupAddress(unsigned long long address, void * & ptr, size_t & len) {
- RegionMap::iterator it = lookupRegion(address);
+lookupAddress(unsigned long long address, Range &range) {
+ RegionMap::const_iterator it = lookupRegion(address);
if (it != regionMap.end()) {
+ const Region & region = it->second;
unsigned long long offset = address - it->first;
- assert(offset < it->second.size);
+ assert(offset < region.size);
- ptr = (char *)it->second.buffer + offset;
- len = it->second.size - offset;
+ range.ptr = (char *)region.buffer + offset;
+ range.len = region.size - offset;
+ range.dims = region.dimensions;
+ range.tracePitch = region.tracePitch;
+ range.realPitch = region.realPitch;
if (retrace::verbosity >= 2) {
std::cout
@@ -205,7 +225,7 @@ lookupAddress(unsigned long long address, void * & ptr, size_t & len) {
<< std::hex
<< "0x" << address
<< " <- "
- << "0x" << (uintptr_t)ptr
+ << "0x" << (uintptr_t)range.ptr
<< std::dec
<< "\n";
}
@@ -218,8 +238,8 @@ lookupAddress(unsigned long long address, void * & ptr, size_t & len) {
std::cerr << "warning: passing high address 0x" << std::hex << address << std::dec << " as uintptr_t\n";
}
- ptr = (void *)(uintptr_t)address;
- len = 0;
+ range.ptr = (void *)(uintptr_t)address;
+ range.len = 0;
}
@@ -228,53 +248,54 @@ class Translator : protected trace::Visitor
protected:
const bool bind;
- void *ptr;
- size_t len;
+ Range ⦥
protected:
void visit(trace::Null *) override {
- ptr = NULL;
- len = 0;
+ range.ptr = nullptr;
+ range.len = 0;
+ range.dims = 0;
}
void visit(trace::Blob *blob) override {
- ptr = blob->toPointer(bind);
- len = blob->size;
+ range.ptr = blob->toPointer(bind);
+ range.len = blob->size;
+ range.dims = 0;
}
void visit(trace::Pointer *p) override {
- lookupAddress(p->value, ptr, len);
+ lookupAddress(p->value, range);
}
public:
- Translator(bool _bind) :
+ Translator(bool _bind, Range &_range) :
bind(_bind),
- ptr(NULL),
- len(0)
- {}
+ range(_range)
+ {
+ range.ptr = nullptr;
+ range.len = 0;
+ range.dims = 0;
+ }
void
- operator() (trace::Value *node, void * & _ptr, size_t & _len) {
+ apply(trace::Value *node) {
_visit(node);
- _ptr = ptr;
- _len = len;
}
};
void
-toRange(trace::Value &value, void * & ptr, size_t & len) {
- Translator(false) (&value, ptr, len);
+toRange(trace::Value &value, Range &range)
+{
+ Translator(false, range).apply(&value);
}
void *
-toPointer(trace::Value &value, bool bind) {
- void * ptr;
- size_t len;
- Translator translator(bind);
- translator(&value, ptr, len);
- (void)len;
- return ptr;
+toPointer(trace::Value &value, bool bind)
+{
+ Range range;
+ Translator(bind, range).apply(&value);
+ return range.ptr;
}
@@ -323,7 +344,7 @@ toObjPointer(trace::Call &call, trace::Value &value) {
warning(call) << "unknown object 0x" << std::hex << address << std::dec << "\n";
}
} else {
- obj = NULL;
+ obj = nullptr;
}
if (retrace::verbosity >= 2) {
diff --git a/retrace/retrace_swizzle.hpp b/retrace/retrace_swizzle.hpp
index 7458971..5b87cd2 100644
--- a/retrace/retrace_swizzle.hpp
+++ b/retrace/retrace_swizzle.hpp
@@ -110,10 +110,22 @@ void
addRegion(trace::Call &call, unsigned long long address, void *buffer, unsigned long long size);
void
+setRegionPitch(unsigned long long address, unsigned dimensions, int tracePitch, int realPitch);
+
+void
delRegionByPointer(void *ptr);
+struct Range
+{
+ void * ptr;
+ size_t len;
+ unsigned dims;
+ int tracePitch;
+ int realPitch;
+};
+
void
-toRange(trace::Value &value, void * & ptr, size_t & len);
+toRange(trace::Value &value, Range & range);
void *
toPointer(trace::Value &value, bool bind = false);
diff --git a/specs/stdapi.py b/specs/stdapi.py
index 50d3e80..52bbb98 100644
--- a/specs/stdapi.py
+++ b/specs/stdapi.py
@@ -335,6 +335,10 @@ class Struct(Type):
def visit(self, visitor, *args, **kwargs):
return visitor.visitStruct(self, *args, **kwargs)
+ def getMemberByName(self, name):
+ memberNames = [memberName for memberType, memberName in self.members]
+ return memberNames.index(name)
+
def Union(kindExpr, kindTypes, contextLess=True):
switchTypes = []
commit dbb01afdc52f5ca5e4a69457037b489aaad0d8b3
Author: Jose Fonseca <jfonseca@vmware.com>
Date: Fri Jun 16 11:45:19 2017 +0100
d3dretrace: Use D3DCREATE_SOFTWARE_VERTEXPROCESSING for --driver=sw.
Ideally we'd use the WARP, but I failed to find a way to use WARP on
demand for D3D9. (The only solution is to disable the GPU driver,
or to use a Windows 8.x/10 VM without any virtual GPU, but neither is
practical.)
diff --git a/retrace/d3d9retrace.py b/retrace/d3d9retrace.py
index 93a3ec4..40e9a44 100644
--- a/retrace/d3d9retrace.py
+++ b/retrace/d3d9retrace.py
@@ -147,6 +147,10 @@ class D3DRetracer(Retracer):
print r' DeviceType = D3DDEVTYPE_HAL;'
print r' break;'
print r' case retrace::DRIVER_SOFTWARE:'
+ print r' BehaviorFlags &= ~D3DCREATE_PUREDEVICE;'
+ print r' BehaviorFlags &= ~D3DCREATE_HARDWARE_VERTEXPROCESSING;'
+ print r' BehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;'
+ print r' break;'
print r' case retrace::DRIVER_REFERENCE:'
print r' DeviceType = D3DDEVTYPE_REF;'
print r' break;'
commit bac0ea039e15c219d243f2ffea40fe9b6181ce32
Author: Jose Fonseca <jfonseca@vmware.com>
Date: Fri Jun 9 15:23:37 2017 +0100
Revert "memtrace: Align blocks to 64 bytes."
This reverts commit f1977beca436a1f8902052bee8ec81d3eccb22fb.
It's incorrect to align to anything other than BLOCK_SIZE, otherwise we
can start touching the following page, which might not exist.
diff --git a/wrappers/memtrace.cpp b/wrappers/memtrace.cpp
index feb2019..fc89a8d 100644
--- a/wrappers/memtrace.cpp
+++ b/wrappers/memtrace.cpp
@@ -60,7 +60,6 @@
#endif
-#define BLOCK_ALIGN 64
#define BLOCK_SIZE 512
@@ -121,7 +120,7 @@ mm_crc32_u32(uint32_t crc, uint32_t current)
uint32_t
hashBlock(const void *p)
{
- assert(lAlignPtr(p, BLOCK_ALIGN) == p);
+ assert((intptr_t)p % BLOCK_SIZE == 0);
uint32_t crc;
@@ -187,33 +186,29 @@ void MemoryShadow::cover(void *_ptr, size_t _size, bool _discard)
{
assert(_ptr);
- const uint8_t *ptr = static_cast<const uint8_t *>(_ptr);
- const uint8_t *basePtr = lAlignPtr(ptr, BLOCK_ALIGN);
-
if (_size != size) {
- static_assert(BLOCK_SIZE % BLOCK_ALIGN == 0, "inconsistent block align/size");
- nBlocks = (ptr + _size - basePtr + BLOCK_SIZE - 1)/BLOCK_SIZE;
+ nBlocks = ((intptr_t)_ptr + _size + BLOCK_SIZE - 1)/BLOCK_SIZE - (intptr_t)_ptr/BLOCK_SIZE;
hashPtr = (uint32_t *)realloc(hashPtr, nBlocks * sizeof *hashPtr);
size = _size;
}
- realPtr = ptr;
+ realPtr = (const uint8_t *)_ptr;
if (_discard) {
zero(_ptr, size);
}
- const uint8_t *blockPtr = basePtr;
+ const uint8_t *p = lAlignPtr((const uint8_t *)_ptr, BLOCK_SIZE);
if (_discard) {
- hashPtr[0] = hashBlock(blockPtr);
+ hashPtr[0] = hashBlock(p);
for (size_t i = 1; i < nBlocks; ++i) {
hashPtr[i] = hashPtr[0];
}
} else {
for (size_t i = 0; i < nBlocks; ++i) {
- hashPtr[i] = hashBlock(blockPtr);
- blockPtr += BLOCK_SIZE;
+ hashPtr[i] = hashBlock(p);
+ p += BLOCK_SIZE;
}
}
}
@@ -224,14 +219,14 @@ void MemoryShadow::update(Callback callback) const
const uint8_t *realStart = realPtr + size;
const uint8_t *realStop = realPtr;
- const uint8_t *blockPtr = lAlignPtr(realPtr, BLOCK_ALIGN);
+ const uint8_t *p = lAlignPtr(realPtr, BLOCK_SIZE);
for (size_t i = 0; i < nBlocks; ++i) {
- uint32_t crc = hashBlock(blockPtr);
+ uint32_t crc = hashBlock(p);
if (crc != hashPtr[i]) {
- realStart = std::min(realStart, blockPtr);
- realStop = std::max(realStop, blockPtr + BLOCK_SIZE);
+ realStart = std::min(realStart, p);
+ realStop = std::max(realStop, p + BLOCK_SIZE);
}
- blockPtr += BLOCK_SIZE;
+ p += BLOCK_SIZE;
}
realStart = std::max(realStart, realPtr);
commit 19acdbb158cd8516f615f0945a120cdbca3455d3
Author: Jose Fonseca <jfonseca@vmware.com>
Date: Fri Jun 9 14:26:58 2017 +0100
highlight: Use ANSI escape codes on Windows 10.
diff --git a/lib/highlight/highlight.cpp b/lib/highlight/highlight.cpp
index f3555f3..c5a8925 100644
--- a/lib/highlight/highlight.cpp
+++ b/lib/highlight/highlight.cpp
@@ -30,6 +30,8 @@
#ifdef _WIN32
+#define DEFINE_CONSOLEV2_PROPERTIES
+
#include <windows.h>
#include <io.h> // _isatty
#include <stdio.h> // _fileno
@@ -62,6 +64,10 @@
#define COMMON_LVB_UNDERSCORE 0x8000
#endif
+#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
+#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
+#endif
+
#else /* !_WIN32 */
#include <unistd.h> // isatty
@@ -97,6 +103,8 @@ public:
static const PlainHighlighter plainHighlighter;
+#define CSI "\33["
+
class AnsiAttribute : public Attribute {
protected:
const char *escape;
@@ -107,18 +115,27 @@ public:
{}
void apply(std::ostream& os) const override {
- os << "\33[" << escape;
+ os << escape;
}
};
-static const AnsiAttribute ansiNormal("0m");
-static const AnsiAttribute ansiBold("1m");
-static const AnsiAttribute ansiItalic("3m");
-static const AnsiAttribute ansiStrike("9m");
-static const AnsiAttribute ansiRed("31m");
-static const AnsiAttribute ansiGreen("32m");
-static const AnsiAttribute ansiBlue("34m");
-static const AnsiAttribute ansiGray("37m");
+static const AnsiAttribute ansiNormal(CSI "0m");
+static const AnsiAttribute ansiBold (CSI "1m");
+static const AnsiAttribute ansiItalic(CSI "3m");
+static const AnsiAttribute ansiStrike(CSI "9m");
+#ifdef _WIN32
+// Brighter colors on Windows to contrast with the background, and match the
+// colors from SetConsoleTextAttribute
+static const AnsiAttribute ansiRed (CSI "91m");
+static const AnsiAttribute ansiGreen (CSI "92m");
+static const AnsiAttribute ansiBlue (CSI "94m");
+static const AnsiAttribute ansiGray (CSI "37m");
+#else
+static const AnsiAttribute ansiRed (CSI "31m");
+static const AnsiAttribute ansiGreen (CSI "32m");
+static const AnsiAttribute ansiBlue (CSI "34m");
+static const AnsiAttribute ansiGray (CSI "37m");
+#endif
/**
@@ -230,16 +247,13 @@ haveAnsi(void)
static bool result = false;
if (!checked) {
- // https://conemu.github.io/en/ConEmuEnvironment.html
- // XXX: Didn't quite work for me
- if (0) {
- const char *conEmuANSI = getenv("ConEmuANSI");
- if (conEmuANSI &&
- strcmp(conEmuANSI, "ON") == 0) {
- result = true;
- checked = true;
- return result;
- }
+ checked = true;
+
+ // http://wiki.winehq.org/DeveloperFaq#detect-wine
+ HMODULE hNtDll = GetModuleHandleA("ntdll");
+ if (hNtDll &&
+ GetProcAddress(hNtDll, "wine_get_version") != nullptr) {
+ return result = true;
}
// Cygwin shell
@@ -247,19 +261,30 @@ haveAnsi(void)
const char *term = getenv("TERM");
if (term &&
strcmp(term, "xterm") == 0) {
- result = true;
- checked = true;
- return result;
+ return result = true;
}
}
- // http://wiki.winehq.org/DeveloperFaq#detect-wine
- HMODULE hNtDll = GetModuleHandleA("ntdll");
- if (hNtDll) {
- result = GetProcAddress(hNtDll, "wine_get_version") != NULL;
+ // Set output mode to handle virtual terminal sequences
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/mt638032.aspx
+ // TODO: Use CONOUT$
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/ms682075.aspx
+ HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
+ if (hOut == INVALID_HANDLE_VALUE) {
+ return false;
}
- checked = true;
+ DWORD dwMode = 0;
+ if (!GetConsoleMode(hOut, &dwMode)) {
+ return false;
+ }
+
+ dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
+ if (SetConsoleMode(hOut, dwMode)) {
+ return result = true;
+ } else {
+ return false;
+ }
}
return result;
commit 60e6514671d4bf23683933c697a85d8a40c6fed3
Author: Jose Fonseca <jfonseca@vmware.com>
Date: Fri Jun 9 13:06:32 2017 +0100
dxgiretrace: Replay query GetData methods.
Prevents all spurious debug layer warnings about query being reused
without data being read.
diff --git a/retrace/dxgiretrace.py b/retrace/dxgiretrace.py
index 77874cc..97d2b59 100755
--- a/retrace/dxgiretrace.py
+++ b/retrace/dxgiretrace.py
@@ -320,6 +320,15 @@ class D3DRetracer(Retracer):
print r' return;'
print r' }'
+ if method.name == 'GetData':
+ print r' pData = _allocator.alloc(DataSize);'
+ print r' do {'
+ self.doInvokeInterfaceMethod(interface, method)
+ print r' GetDataFlags = 0; // Prevent infinite loop'
+ print r' } while (_result == S_FALSE);'
+ self.checkResult(interface, method)
+ print r' return;'
+
Retracer.invokeInterfaceMethod(self, interface, method)
if method.name in ('AcquireSync', 'ReleaseSync'):
diff --git a/specs/d3d10.py b/specs/d3d10.py
index 2161a5f..2d8f485 100644
--- a/specs/d3d10.py
+++ b/specs/d3d10.py
@@ -837,7 +837,7 @@ ID3D10SamplerState.methods += [
ID3D10Asynchronous.methods += [
StdMethod(Void, "Begin", []),
StdMethod(Void, "End", []),
- StdMethod(HRESULT, "GetData", [Out(D3D10_QUERY_DATA, "pData"), (UINT, "DataSize"), (D3D10_ASYNC_GETDATA_FLAG, "GetDataFlags")], sideeffects=False),
+ StdMethod(HRESULT, "GetData", [Out(D3D10_QUERY_DATA, "pData"), (UINT, "DataSize"), (D3D10_ASYNC_GETDATA_FLAG, "GetDataFlags")]),
StdMethod(UINT, "GetDataSize", [], sideeffects=False),
]
diff --git a/specs/d3d11.py b/specs/d3d11.py
index 2fc2771..8596189 100644
--- a/specs/d3d11.py
+++ b/specs/d3d11.py
@@ -1278,7 +1278,7 @@ ID3D11DeviceContext.methods += [
StdMethod(Void, "VSSetSamplers", [(UINT, "StartSlot"), (UINT, "NumSamplers"), (Array(Const(ObjPointer(ID3D11SamplerState)), "NumSamplers"), "ppSamplers")]),
StdMethod(Void, "Begin", [(ObjPointer(ID3D11Asynchronous), "pAsync")]),
StdMethod(Void, "End", [(ObjPointer(ID3D11Asynchronous), "pAsync")]),
- StdMethod(HRESULT, "GetData", [(ObjPointer(ID3D11Asynchronous), "pAsync"), Out(D3D11_QUERY_DATA, "pData"), (UINT, "DataSize"), (D3D11_ASYNC_GETDATA_FLAG, "GetDataFlags")], sideeffects=False),
+ StdMethod(HRESULT, "GetData", [(ObjPointer(ID3D11Asynchronous), "pAsync"), Out(D3D11_QUERY_DATA, "pData"), (UINT, "DataSize"), (D3D11_ASYNC_GETDATA_FLAG, "GetDataFlags")]),
StdMethod(Void, "SetPredication", [(ObjPointer(ID3D11Predicate), "pPredicate"), (BOOL, "PredicateValue")]),
StdMethod(Void, "GSSetShaderResources", [(UINT, "StartSlot"), (UINT, "NumViews"), (Array(Const(ObjPointer(ID3D11ShaderResourceView)), "NumViews"), "ppShaderResourceViews")]),
StdMethod(Void, "GSSetSamplers", [(UINT, "StartSlot"), (UINT, "NumSamplers"), (Array(Const(ObjPointer(ID3D11SamplerState)), "NumSamplers"), "ppSamplers")]),
commit 2264546d148be8f7c46790a2f91b83ab8c7ff663
Author: Jose Fonseca <jfonseca@vmware.com>
Date: Sat Jun 3 21:59:09 2017 +0100
Refer lack of Android support to issue #521.
Instead of mailing list.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3f5e51e..4827926 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -44,7 +44,7 @@ option (ENABLE_ASAN "Enable Address Sanitizer" OFF)
option (ENABLE_TESTS "Enable additional tests" OFF)
if (ANDROID)
- message (FATAL_ERROR "Android is no longer supported (https://goo.gl/yQEXFd)")
+ message (FATAL_ERROR "Android is no longer supported (https://git.io/vH2gW)")
endif ()
# Proprietary Linux games often ship their own libraries (zlib, libstdc++,
diff --git a/docs/INSTALL.markdown b/docs/INSTALL.markdown
index 013877f..64ae639 100644
--- a/docs/INSTALL.markdown
+++ b/docs/INSTALL.markdown
@@ -82,9 +82,7 @@ Build as:
# Android #
-Android is no longer supported. See https://goo.gl/yQEXFd for the reason why.
-If you need Android support, your best bet is to try an old release (search for
-android branch upstream.)
+Android is no longer supported. See https://git.io/vH2gW for more information.
# Windows #
commit 63194b2573176ef34efce1a5c8b08e624b8dddf5
Author: George Kyriazis <george.kyriazis@intel.com>
Date: Thu Jun 1 16:23:16 2017 +0100
dispatch: dlopen libGL.so with RTLD_DEEPBIND.
According to the dlopen() docs, a deep bind will resolve unresolved
symbols inside the dlopen()-ed library, within the library itself first.
This way the symbols in the Mesa's GLX_functions array will get resolved
inside Mesa, and not with apitrace symbols.
diff --git a/dispatch/glproc_egl.cpp b/dispatch/glproc_egl.cpp
index 07714ae..bc6156e 100644
--- a/dispatch/glproc_egl.cpp
+++ b/dispatch/glproc_egl.cpp
@@ -89,7 +89,7 @@ _getPublicProcAddress(const char *procName)
if (procName[0] == 'e' && procName[1] == 'g' && procName[2] == 'l') {
static void *libEGL = NULL;
if (!libEGL) {
- libEGL = _dlopen("libEGL.so", RTLD_LOCAL | RTLD_LAZY);
+ libEGL = _dlopen("libEGL.so", RTLD_LOCAL | RTLD_LAZY | RTLD_DEEPBIND);
if (!libEGL) {
return NULL;
}
@@ -132,7 +132,7 @@ _getPublicProcAddress(const char *procName)
static void *libGLESv2 = NULL;
if (!libGLESv2) {
- libGLESv2 = _dlopen("libGLESv2.so", RTLD_LOCAL | RTLD_LAZY);
+ libGLESv2 = _dlopen("libGLESv2.so", RTLD_LOCAL | RTLD_LAZY | RTLD_DEEPBIND);
}
if (libGLESv2) {
proc = dlsym(libGLESv2, procName);
@@ -143,7 +143,7 @@ _getPublicProcAddress(const char *procName)
static void *libGLESv1 = NULL;
if (!libGLESv1) {
- libGLESv1 = _dlopen("libGLESv1_CM.so", RTLD_LOCAL | RTLD_LAZY);
+ libGLESv1 = _dlopen("libGLESv1_CM.so", RTLD_LOCAL | RTLD_LAZY | RTLD_DEEPBIND);
}
if (libGLESv1) {
proc = dlsym(libGLESv1, procName);
diff --git a/dispatch/glproc_gl.cpp b/dispatch/glproc_gl.cpp
index 3d963fb..5d7903a 100644
--- a/dispatch/glproc_gl.cpp
+++ b/dispatch/glproc_gl.cpp
@@ -200,7 +200,7 @@ void * _libgl_sym(const char *symbol)
* exposes symbols to it.
*/
- _libGlHandle = _dlopen(libgl_filename, RTLD_GLOBAL | RTLD_LAZY);
+ _libGlHandle = _dlopen(libgl_filename, RTLD_GLOBAL | RTLD_LAZY | RTLD_DEEPBIND);
if (!_libGlHandle) {
os::log("apitrace: error: couldn't find libGL.so\n");
return NULL;
commit cbb48c56b67a3a1948d7ec8b958c8d13c2c85b57
Author: Jose Fonseca <jfonseca@vmware.com>
Date: Thu Jun 1 14:37:12 2017 +0100
cmake: Allow to build additional tests simultanously.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0e479cb..3f5e51e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -41,6 +41,8 @@ option (ENABLE_FRAME_POINTER "Disable frame pointer omission" ON)
option (ENABLE_ASAN "Enable Address Sanitizer" OFF)
+option (ENABLE_TESTS "Enable additional tests" OFF)
+
if (ANDROID)
message (FATAL_ERROR "Android is no longer supported (https://goo.gl/yQEXFd)")
endif ()
@@ -549,7 +551,21 @@ endif ()
# GUI
if (ENABLE_GUI AND Qt5Widgets_FOUND AND Qt5Network_FOUND)
- add_subdirectory(gui)
+ add_subdirectory (gui)
+endif ()
+
+
+##############################################################################
+# Additional tests
+
+if (ENABLE_TESTS)
+ if (NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tests/CMakeLists.txt")
+ message (EMIT_ERROR
+ "tests/CMakeLists.txt is missing, please do\n"
+ " git clone https://github.com/apitrace/apitrace-tests tests")
+ else ()
+ add_subdirectory (tests)
+ endif ()
endif ()
commit b423de11db06def038650410950fc3969eae467c
Author: Jose Fonseca <jfonseca@vmware.com>
Date: Thu Jun 1 14:36:14 2017 +0100
d3dretrace: Handle overlapping IDirect3DCubeTexture9 locks on different faces.
diff --git a/retrace/d3d9retrace.py b/retrace/d3d9retrace.py
index 8d0f315..93a3ec4 100644
--- a/retrace/d3d9retrace.py
+++ b/retrace/d3d9retrace.py
@@ -233,13 +233,17 @@ class D3DRetracer(Retracer):
print r' d3dretrace::processEvents();'
def mapping_subkey():
- if 'Level' in method.argNames():
+ # A single texture object might have multiple mappings. This key
+ # allows to tell them apart.
+ if 'FaceType' in method.argNames():
+ return ('static_cast<UINT>(FaceType) + Level*6',)
+ elif 'Level' in method.argNames():
return ('Level',)
else:
return ('0',)
if method.name in ('Lock', 'LockRect', 'LockBox'):
- print ' VOID *_pbData = NULL;'
+ print ' VOID *_pbData = nullptr;'
print ' size_t _MappedSize = 0;'
if method.name == 'Lock':
# Ignore D3DLOCK_READONLY for buffers.
@@ -257,12 +261,12 @@ class D3DRetracer(Retracer):
print ' }'
if method.name in ('Unlock', 'UnlockRect', 'UnlockBox'):
- print ' VOID *_pbData = 0;'
+ print ' VOID *_pbData = nullptr;'
print ' MappingKey _mappingKey(_this, %s);' % mapping_subkey()
print ' _pbData = _maps[_mappingKey];'
print ' if (_pbData) {'
print ' retrace::delRegionByPointer(_pbData);'
- print ' _maps[_mappingKey] = 0;'
+ print ' _maps[_mappingKey] = nullptr;'
print ' }'
if interface.name == 'IDirectXVideoDecoder':
@@ -275,7 +279,7 @@ class D3DRetracer(Retracer):
print ' void *_pBuffer = _maps[_mappingKey];'
print ' if (_pBuffer) {'
print ' retrace::delRegionByPointer(_pBuffer);'
- print ' _maps[_mappingKey] = 0;'
+ print ' _maps[_mappingKey] = nullptr;'
print ' }'
def handleFailure(self, interface, methodOrFunction):
commit a0cd097d4fc82c5faccf16bad24288ef15028c54
Author: Jose Fonseca <jfonseca@vmware.com>
Date: Thu Jun 1 13:29:35 2017 +0100
d3d9trace: Handle overlapping IDirect3DCubeTexture9 locks on different faces.
diff --git a/wrappers/d3d9trace.py b/wrappers/d3d9trace.py
index 5b966cb..92da8c0 100644
--- a/wrappers/d3d9trace.py
+++ b/wrappers/d3d9trace.py
@@ -78,7 +78,11 @@ class D3D9Tracer(DllTracer):
if method.name in ('Unlock', 'UnlockRect', 'UnlockBox'):
if interface.base.name == 'IDirect3DBaseTexture9':
assert method.getArgByName('Level') is not None
- print ' std::map<UINT, std::pair<size_t, VOID *> >::iterator it = _MappedData.find(Level);'
+ if method.getArgByName('FaceType'):
+ print r' UINT _Key = static_cast<UINT>(FaceType) + Level*6;'
+ else:
+ print r' UINT _Key = Level;'
+ print ' std::map<UINT, std::pair<size_t, VOID *> >::iterator it = _MappedData.find(_Key);'
print ' if (it != _MappedData.end()) {'
self.emit_memcpy('(LPBYTE)it->second.second', 'it->second.first')
print ' _MappedData.erase(it);'
@@ -101,13 +105,17 @@ class D3D9Tracer(DllTracer):
if method.name in ('Lock', 'LockRect', 'LockBox'):
if interface.base.name == 'IDirect3DBaseTexture9':
assert method.getArgByName('Level') is not None
+ if method.getArgByName('FaceType'):
+ print r' UINT _Key = static_cast<UINT>(FaceType) + Level*6;'
+ else:
+ print r' UINT _Key = Level;'
print ' if (SUCCEEDED(_result) && !(Flags & D3DLOCK_READONLY)) {'
print ' size_t mappedSize;'
print ' VOID * pbData;'
print ' _getMapInfo(_this, %s, pbData, mappedSize);' % ', '.join(method.argNames()[:-1])
- print ' _MappedData[Level] = std::make_pair(mappedSize, pbData);'
+ print ' _MappedData[_Key] = std::make_pair(mappedSize, pbData);'
print ' } else {'
- print ' _MappedData.erase(Level);'
+ print ' _MappedData.erase(_Key);'
print ' }'
else:
# FIXME: handle recursive locks
commit d0094a2813fde0df4dfe36bd551c060694a0cb13
Author: Jose Fonseca <jfonseca@vmware.com>
Date: Tue May 30 12:31:37 2017 +0100
d3dretrace: Abort on D3DERR_DEVICELOST.
Like we already did for DXGI_ERROR_DEVICE_REMOVED.
To do this, separate checking result, from handling failure.
Reply to: