summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/auxiliary/util')
-rw-r--r--src/gallium/auxiliary/util/dbghelp.h1265
-rw-r--r--src/gallium/auxiliary/util/u_blit.c9
-rw-r--r--src/gallium/auxiliary/util/u_blitter.c128
-rw-r--r--src/gallium/auxiliary/util/u_blitter.h16
-rw-r--r--src/gallium/auxiliary/util/u_debug.c80
-rw-r--r--src/gallium/auxiliary/util/u_debug.h37
-rw-r--r--src/gallium/auxiliary/util/u_debug_refcnt.c12
-rw-r--r--src/gallium/auxiliary/util/u_debug_symbol.c95
-rw-r--r--src/gallium/auxiliary/util/u_draw_quad.c14
-rw-r--r--src/gallium/auxiliary/util/u_draw_quad.h5
-rw-r--r--src/gallium/auxiliary/util/u_dump_state.c1
-rw-r--r--src/gallium/auxiliary/util/u_format.h42
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.c4
-rw-r--r--src/gallium/auxiliary/util/u_index_modify.c18
-rw-r--r--src/gallium/auxiliary/util/u_inlines.h19
-rw-r--r--src/gallium/auxiliary/util/u_math.h14
-rw-r--r--src/gallium/auxiliary/util/u_resource.c2
-rw-r--r--src/gallium/auxiliary/util/u_tile.c81
-rw-r--r--src/gallium/auxiliary/util/u_tile.h24
-rw-r--r--src/gallium/auxiliary/util/u_transfer.c7
-rw-r--r--src/gallium/auxiliary/util/u_transfer.h12
-rw-r--r--src/gallium/auxiliary/util/u_upload_mgr.c13
-rw-r--r--src/gallium/auxiliary/util/u_vbuf_mgr.c601
-rw-r--r--src/gallium/auxiliary/util/u_vbuf_mgr.h121
24 files changed, 2411 insertions, 209 deletions
diff --git a/src/gallium/auxiliary/util/dbghelp.h b/src/gallium/auxiliary/util/dbghelp.h
new file mode 100644
index 00000000000..bc7c53cf9f2
--- /dev/null
+++ b/src/gallium/auxiliary/util/dbghelp.h
@@ -0,0 +1,1265 @@
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER.PD within this package.
+ */
+#ifndef _DBGHELP_
+#define _DBGHELP_
+
+#ifdef _WIN64
+#ifndef _IMAGEHLP64
+#define _IMAGEHLP64
+#endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define IMAGEAPI DECLSPEC_IMPORT WINAPI
+#define DBHLP_DEPRECIATED __declspec(deprecated)
+
+#define DBHLPAPI IMAGEAPI
+
+#define IMAGE_SEPARATION (64*1024)
+
+ typedef struct _LOADED_IMAGE {
+ PSTR ModuleName;
+ HANDLE hFile;
+ PUCHAR MappedAddress;
+#ifdef _IMAGEHLP64
+ PIMAGE_NT_HEADERS64 FileHeader;
+#else
+ PIMAGE_NT_HEADERS32 FileHeader;
+#endif
+ PIMAGE_SECTION_HEADER LastRvaSection;
+ ULONG NumberOfSections;
+ PIMAGE_SECTION_HEADER Sections;
+ ULONG Characteristics;
+ BOOLEAN fSystemImage;
+ BOOLEAN fDOSImage;
+ LIST_ENTRY Links;
+ ULONG SizeOfImage;
+ } LOADED_IMAGE,*PLOADED_IMAGE;
+
+#define MAX_SYM_NAME 2000
+
+ typedef BOOL (CALLBACK *PFIND_DEBUG_FILE_CALLBACK)(HANDLE FileHandle,PSTR FileName,PVOID CallerData);
+ typedef BOOL (CALLBACK *PFINDFILEINPATHCALLBACK)(PSTR filename,PVOID context);
+ typedef BOOL (CALLBACK *PFIND_EXE_FILE_CALLBACK)(HANDLE FileHandle,PSTR FileName,PVOID CallerData);
+
+ typedef BOOL (WINAPI *PSYMBOLSERVERPROC)(LPCSTR,LPCSTR,PVOID,DWORD,DWORD,LPSTR);
+ typedef BOOL (WINAPI *PSYMBOLSERVEROPENPROC)(VOID);
+ typedef BOOL (WINAPI *PSYMBOLSERVERCLOSEPROC)(VOID);
+ typedef BOOL (WINAPI *PSYMBOLSERVERSETOPTIONSPROC)(UINT_PTR,ULONG64);
+ typedef BOOL (CALLBACK WINAPI *PSYMBOLSERVERCALLBACKPROC)(UINT_PTR action,ULONG64 data,ULONG64 context);
+ typedef UINT_PTR (WINAPI *PSYMBOLSERVERGETOPTIONSPROC)();
+ typedef BOOL (WINAPI *PSYMBOLSERVERPINGPROC)(LPCSTR);
+
+ HANDLE IMAGEAPI FindDebugInfoFile(PSTR FileName,PSTR SymbolPath,PSTR DebugFilePath);
+ HANDLE IMAGEAPI FindDebugInfoFileEx(PSTR FileName,PSTR SymbolPath,PSTR DebugFilePath,PFIND_DEBUG_FILE_CALLBACK Callback,PVOID CallerData);
+ BOOL IMAGEAPI SymFindFileInPath(HANDLE hprocess,LPSTR SearchPath,LPSTR FileName,PVOID id,DWORD two,DWORD three,DWORD flags,LPSTR FoundFile,PFINDFILEINPATHCALLBACK callback,PVOID context);
+ HANDLE IMAGEAPI FindExecutableImage(PSTR FileName,PSTR SymbolPath,PSTR ImageFilePath);
+ HANDLE IMAGEAPI FindExecutableImageEx(PSTR FileName,PSTR SymbolPath,PSTR ImageFilePath,PFIND_EXE_FILE_CALLBACK Callback,PVOID CallerData);
+ PIMAGE_NT_HEADERS IMAGEAPI ImageNtHeader(PVOID Base);
+ PVOID IMAGEAPI ImageDirectoryEntryToDataEx(PVOID Base,BOOLEAN MappedAsImage,USHORT DirectoryEntry,PULONG Size,PIMAGE_SECTION_HEADER *FoundHeader);
+ PVOID IMAGEAPI ImageDirectoryEntryToData(PVOID Base,BOOLEAN MappedAsImage,USHORT DirectoryEntry,PULONG Size);
+ PIMAGE_SECTION_HEADER IMAGEAPI ImageRvaToSection(PIMAGE_NT_HEADERS NtHeaders,PVOID Base,ULONG Rva);
+ PVOID IMAGEAPI ImageRvaToVa(PIMAGE_NT_HEADERS NtHeaders,PVOID Base,ULONG Rva,PIMAGE_SECTION_HEADER *LastRvaSection);
+
+#define SSRVOPT_CALLBACK 0x0001
+#define SSRVOPT_DWORD 0x0002
+#define SSRVOPT_DWORDPTR 0x0004
+#define SSRVOPT_GUIDPTR 0x0008
+#define SSRVOPT_OLDGUIDPTR 0x0010
+#define SSRVOPT_UNATTENDED 0x0020
+#define SSRVOPT_NOCOPY 0x0040
+#define SSRVOPT_PARENTWIN 0x0080
+#define SSRVOPT_PARAMTYPE 0x0100
+#define SSRVOPT_SECURE 0x0200
+#define SSRVOPT_TRACE 0x0400
+#define SSRVOPT_SETCONTEXT 0x0800
+#define SSRVOPT_PROXY 0x1000
+#define SSRVOPT_DOWNSTREAM_STORE 0x2000
+#define SSRVOPT_RESET ((ULONG_PTR)-1)
+
+#define SSRVACTION_TRACE 1
+#define SSRVACTION_QUERYCANCEL 2
+#define SSRVACTION_EVENT 3
+
+#ifndef _WIN64
+
+ typedef struct _IMAGE_DEBUG_INFORMATION {
+ LIST_ENTRY List;
+ DWORD ReservedSize;
+ PVOID ReservedMappedBase;
+ USHORT ReservedMachine;
+ USHORT ReservedCharacteristics;
+ DWORD ReservedCheckSum;
+ DWORD ImageBase;
+ DWORD SizeOfImage;
+ DWORD ReservedNumberOfSections;
+ PIMAGE_SECTION_HEADER ReservedSections;
+ DWORD ReservedExportedNamesSize;
+ PSTR ReservedExportedNames;
+ DWORD ReservedNumberOfFunctionTableEntries;
+ PIMAGE_FUNCTION_ENTRY ReservedFunctionTableEntries;
+ DWORD ReservedLowestFunctionStartingAddress;
+ DWORD ReservedHighestFunctionEndingAddress;
+ DWORD ReservedNumberOfFpoTableEntries;
+ PFPO_DATA ReservedFpoTableEntries;
+ DWORD SizeOfCoffSymbols;
+ PIMAGE_COFF_SYMBOLS_HEADER CoffSymbols;
+ DWORD ReservedSizeOfCodeViewSymbols;
+ PVOID ReservedCodeViewSymbols;
+ PSTR ImageFilePath;
+ PSTR ImageFileName;
+ PSTR ReservedDebugFilePath;
+ DWORD ReservedTimeDateStamp;
+ BOOL ReservedRomImage;
+ PIMAGE_DEBUG_DIRECTORY ReservedDebugDirectory;
+ DWORD ReservedNumberOfDebugDirectories;
+ DWORD ReservedOriginalFunctionTableBaseAddress;
+ DWORD Reserved[2 ];
+ } IMAGE_DEBUG_INFORMATION,*PIMAGE_DEBUG_INFORMATION;
+
+ PIMAGE_DEBUG_INFORMATION IMAGEAPI MapDebugInformation(HANDLE FileHandle,PSTR FileName,PSTR SymbolPath,DWORD ImageBase);
+ BOOL IMAGEAPI UnmapDebugInformation(PIMAGE_DEBUG_INFORMATION DebugInfo);
+#endif
+
+ typedef BOOL (CALLBACK *PENUMDIRTREE_CALLBACK)(LPCSTR FilePath,PVOID CallerData);
+
+ BOOL IMAGEAPI SearchTreeForFile(PSTR RootPath,PSTR InputPathName,PSTR OutputPathBuffer);
+ BOOL IMAGEAPI EnumDirTree(HANDLE hProcess,PSTR RootPath,PSTR InputPathName,PSTR OutputPathBuffer,PENUMDIRTREE_CALLBACK Callback,PVOID CallbackData);
+ BOOL IMAGEAPI MakeSureDirectoryPathExists(PCSTR DirPath);
+
+#define UNDNAME_COMPLETE (0x0000)
+#define UNDNAME_NO_LEADING_UNDERSCORES (0x0001)
+#define UNDNAME_NO_MS_KEYWORDS (0x0002)
+#define UNDNAME_NO_FUNCTION_RETURNS (0x0004)
+#define UNDNAME_NO_ALLOCATION_MODEL (0x0008)
+#define UNDNAME_NO_ALLOCATION_LANGUAGE (0x0010)
+#define UNDNAME_NO_MS_THISTYPE (0x0020)
+#define UNDNAME_NO_CV_THISTYPE (0x0040)
+#define UNDNAME_NO_THISTYPE (0x0060)
+#define UNDNAME_NO_ACCESS_SPECIFIERS (0x0080)
+#define UNDNAME_NO_THROW_SIGNATURES (0x0100)
+#define UNDNAME_NO_MEMBER_TYPE (0x0200)
+#define UNDNAME_NO_RETURN_UDT_MODEL (0x0400)
+#define UNDNAME_32_BIT_DECODE (0x0800)
+#define UNDNAME_NAME_ONLY (0x1000)
+#define UNDNAME_NO_ARGUMENTS (0x2000)
+#define UNDNAME_NO_SPECIAL_SYMS (0x4000)
+
+ DWORD IMAGEAPI WINAPI UnDecorateSymbolName(PCSTR DecoratedName,PSTR UnDecoratedName,DWORD UndecoratedLength,DWORD Flags);
+
+#define DBHHEADER_DEBUGDIRS 0x1
+
+ typedef struct _MODLOAD_DATA {
+ DWORD ssize;
+ DWORD ssig;
+ PVOID data;
+ DWORD size;
+ DWORD flags;
+ } MODLOAD_DATA,*PMODLOAD_DATA;
+
+ typedef enum {
+ AddrMode1616,AddrMode1632,AddrModeReal,AddrModeFlat
+ } ADDRESS_MODE;
+
+ typedef struct _tagADDRESS64 {
+ DWORD64 Offset;
+ WORD Segment;
+ ADDRESS_MODE Mode;
+ } ADDRESS64,*LPADDRESS64;
+
+#ifdef _IMAGEHLP64
+#define ADDRESS ADDRESS64
+#define LPADDRESS LPADDRESS64
+#else
+ typedef struct _tagADDRESS {
+ DWORD Offset;
+ WORD Segment;
+ ADDRESS_MODE Mode;
+ } ADDRESS,*LPADDRESS;
+
+ static __inline void Address32To64(LPADDRESS a32,LPADDRESS64 a64) {
+ a64->Offset = (ULONG64)(LONG64)(LONG)a32->Offset;
+ a64->Segment = a32->Segment;
+ a64->Mode = a32->Mode;
+ }
+
+ static __inline void Address64To32(LPADDRESS64 a64,LPADDRESS a32) {
+ a32->Offset = (ULONG)a64->Offset;
+ a32->Segment = a64->Segment;
+ a32->Mode = a64->Mode;
+ }
+#endif
+
+ typedef struct _KDHELP64 {
+ DWORD64 Thread;
+ DWORD ThCallbackStack;
+ DWORD ThCallbackBStore;
+ DWORD NextCallback;
+ DWORD FramePointer;
+ DWORD64 KiCallUserMode;
+ DWORD64 KeUserCallbackDispatcher;
+ DWORD64 SystemRangeStart;
+ DWORD64 Reserved[8];
+ } KDHELP64,*PKDHELP64;
+
+#ifdef _IMAGEHLP64
+#define KDHELP KDHELP64
+#define PKDHELP PKDHELP64
+#else
+ typedef struct _KDHELP {
+ DWORD Thread;
+ DWORD ThCallbackStack;
+ DWORD NextCallback;
+ DWORD FramePointer;
+ DWORD KiCallUserMode;
+ DWORD KeUserCallbackDispatcher;
+ DWORD SystemRangeStart;
+ DWORD ThCallbackBStore;
+ DWORD Reserved[8];
+ } KDHELP,*PKDHELP;
+
+ static __inline void KdHelp32To64(PKDHELP p32,PKDHELP64 p64) {
+ p64->Thread = p32->Thread;
+ p64->ThCallbackStack = p32->ThCallbackStack;
+ p64->NextCallback = p32->NextCallback;
+ p64->FramePointer = p32->FramePointer;
+ p64->KiCallUserMode = p32->KiCallUserMode;
+ p64->KeUserCallbackDispatcher = p32->KeUserCallbackDispatcher;
+ p64->SystemRangeStart = p32->SystemRangeStart;
+ }
+#endif
+
+ typedef struct _tagSTACKFRAME64 {
+ ADDRESS64 AddrPC;
+ ADDRESS64 AddrReturn;
+ ADDRESS64 AddrFrame;
+ ADDRESS64 AddrStack;
+ ADDRESS64 AddrBStore;
+ PVOID FuncTableEntry;
+ DWORD64 Params[4];
+ BOOL Far;
+ BOOL Virtual;
+ DWORD64 Reserved[3];
+ KDHELP64 KdHelp;
+ } STACKFRAME64,*LPSTACKFRAME64;
+
+#ifdef _IMAGEHLP64
+#define STACKFRAME STACKFRAME64
+#define LPSTACKFRAME LPSTACKFRAME64
+#else
+ typedef struct _tagSTACKFRAME {
+ ADDRESS AddrPC;
+ ADDRESS AddrReturn;
+ ADDRESS AddrFrame;
+ ADDRESS AddrStack;
+ PVOID FuncTableEntry;
+ DWORD Params[4];
+ BOOL Far;
+ BOOL Virtual;
+ DWORD Reserved[3];
+ KDHELP KdHelp;
+ ADDRESS AddrBStore;
+ } STACKFRAME,*LPSTACKFRAME;
+#endif
+
+ typedef BOOL (WINAPI *PREAD_PROCESS_MEMORY_ROUTINE64)(HANDLE hProcess,DWORD64 qwBaseAddress,PVOID lpBuffer,DWORD nSize,LPDWORD lpNumberOfBytesRead);
+ typedef PVOID (WINAPI *PFUNCTION_TABLE_ACCESS_ROUTINE64)(HANDLE hProcess,DWORD64 AddrBase);
+ typedef DWORD64 (WINAPI *PGET_MODULE_BASE_ROUTINE64)(HANDLE hProcess,DWORD64 Address);
+ typedef DWORD64 (WINAPI *PTRANSLATE_ADDRESS_ROUTINE64)(HANDLE hProcess,HANDLE hThread,LPADDRESS64 lpaddr);
+
+ BOOL IMAGEAPI StackWalk64(DWORD MachineType,HANDLE hProcess,HANDLE hThread,LPSTACKFRAME64 StackFrame,PVOID ContextRecord,PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress);
+
+#ifdef _IMAGEHLP64
+#define PREAD_PROCESS_MEMORY_ROUTINE PREAD_PROCESS_MEMORY_ROUTINE64
+#define PFUNCTION_TABLE_ACCESS_ROUTINE PFUNCTION_TABLE_ACCESS_ROUTINE64
+#define PGET_MODULE_BASE_ROUTINE PGET_MODULE_BASE_ROUTINE64
+#define PTRANSLATE_ADDRESS_ROUTINE PTRANSLATE_ADDRESS_ROUTINE64
+#define StackWalk StackWalk64
+#else
+ typedef BOOL (WINAPI *PREAD_PROCESS_MEMORY_ROUTINE)(HANDLE hProcess,DWORD lpBaseAddress,PVOID lpBuffer,DWORD nSize,PDWORD lpNumberOfBytesRead);
+ typedef PVOID (WINAPI *PFUNCTION_TABLE_ACCESS_ROUTINE)(HANDLE hProcess,DWORD AddrBase);
+ typedef DWORD (WINAPI *PGET_MODULE_BASE_ROUTINE)(HANDLE hProcess,DWORD Address);
+ typedef DWORD (WINAPI *PTRANSLATE_ADDRESS_ROUTINE)(HANDLE hProcess,HANDLE hThread,LPADDRESS lpaddr);
+
+ BOOL IMAGEAPI StackWalk(DWORD MachineType,HANDLE hProcess,HANDLE hThread,LPSTACKFRAME StackFrame,PVOID ContextRecord,PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine,PTRANSLATE_ADDRESS_ROUTINE TranslateAddress);
+#endif
+
+#define API_VERSION_NUMBER 9
+
+ typedef struct API_VERSION {
+ USHORT MajorVersion;
+ USHORT MinorVersion;
+ USHORT Revision;
+ USHORT Reserved;
+ } API_VERSION,*LPAPI_VERSION;
+
+ LPAPI_VERSION IMAGEAPI ImagehlpApiVersion(VOID);
+ LPAPI_VERSION IMAGEAPI ImagehlpApiVersionEx(LPAPI_VERSION AppVersion);
+ DWORD IMAGEAPI GetTimestampForLoadedLibrary(HMODULE Module);
+
+ typedef BOOL (CALLBACK *PSYM_ENUMMODULES_CALLBACK64)(PSTR ModuleName,DWORD64 BaseOfDll,PVOID UserContext);
+ typedef BOOL (CALLBACK *PSYM_ENUMSYMBOLS_CALLBACK64)(PSTR SymbolName,DWORD64 SymbolAddress,ULONG SymbolSize,PVOID UserContext);
+ typedef BOOL (CALLBACK *PSYM_ENUMSYMBOLS_CALLBACK64W)(PWSTR SymbolName,DWORD64 SymbolAddress,ULONG SymbolSize,PVOID UserContext);
+ typedef BOOL (CALLBACK *PENUMLOADED_MODULES_CALLBACK64)(PSTR ModuleName,DWORD64 ModuleBase,ULONG ModuleSize,PVOID UserContext);
+ typedef BOOL (CALLBACK *PSYMBOL_REGISTERED_CALLBACK64)(HANDLE hProcess,ULONG ActionCode,ULONG64 CallbackData,ULONG64 UserContext);
+ typedef PVOID (CALLBACK *PSYMBOL_FUNCENTRY_CALLBACK)(HANDLE hProcess,DWORD AddrBase,PVOID UserContext);
+ typedef PVOID (CALLBACK *PSYMBOL_FUNCENTRY_CALLBACK64)(HANDLE hProcess,ULONG64 AddrBase,ULONG64 UserContext);
+
+#ifdef _IMAGEHLP64
+#define PSYM_ENUMMODULES_CALLBACK PSYM_ENUMMODULES_CALLBACK64
+#define PSYM_ENUMSYMBOLS_CALLBACK PSYM_ENUMSYMBOLS_CALLBACK64
+#define PSYM_ENUMSYMBOLS_CALLBACKW PSYM_ENUMSYMBOLS_CALLBACK64W
+#define PENUMLOADED_MODULES_CALLBACK PENUMLOADED_MODULES_CALLBACK64
+#define PSYMBOL_REGISTERED_CALLBACK PSYMBOL_REGISTERED_CALLBACK64
+#define PSYMBOL_FUNCENTRY_CALLBACK PSYMBOL_FUNCENTRY_CALLBACK64
+#else
+ typedef BOOL (CALLBACK *PSYM_ENUMMODULES_CALLBACK)(PSTR ModuleName,ULONG BaseOfDll,PVOID UserContext);
+ typedef BOOL (CALLBACK *PSYM_ENUMSYMBOLS_CALLBACK)(PSTR SymbolName,ULONG SymbolAddress,ULONG SymbolSize,PVOID UserContext);
+ typedef BOOL (CALLBACK *PSYM_ENUMSYMBOLS_CALLBACKW)(PWSTR SymbolName,ULONG SymbolAddress,ULONG SymbolSize,PVOID UserContext);
+ typedef BOOL (CALLBACK *PENUMLOADED_MODULES_CALLBACK)(PSTR ModuleName,ULONG ModuleBase,ULONG ModuleSize,PVOID UserContext);
+ typedef BOOL (CALLBACK *PSYMBOL_REGISTERED_CALLBACK)(HANDLE hProcess,ULONG ActionCode,PVOID CallbackData,PVOID UserContext);
+#endif
+
+#define SYMFLAG_VALUEPRESENT 0x00000001
+#define SYMFLAG_REGISTER 0x00000008
+#define SYMFLAG_REGREL 0x00000010
+#define SYMFLAG_FRAMEREL 0x00000020
+#define SYMFLAG_PARAMETER 0x00000040
+#define SYMFLAG_LOCAL 0x00000080
+#define SYMFLAG_CONSTANT 0x00000100
+#define SYMFLAG_EXPORT 0x00000200
+#define SYMFLAG_FORWARDER 0x00000400
+#define SYMFLAG_FUNCTION 0x00000800
+#define SYMFLAG_VIRTUAL 0x00001000
+#define SYMFLAG_THUNK 0x00002000
+#define SYMFLAG_TLSREL 0x00004000
+
+ typedef enum {
+ SymNone = 0,SymCoff,SymCv,SymPdb,SymExport,SymDeferred,SymSym,SymDia,SymVirtual,NumSymTypes
+ } SYM_TYPE;
+
+ typedef struct _IMAGEHLP_SYMBOL64 {
+ DWORD SizeOfStruct;
+ DWORD64 Address;
+ DWORD Size;
+ DWORD Flags;
+ DWORD MaxNameLength;
+ CHAR Name[1];
+ } IMAGEHLP_SYMBOL64,*PIMAGEHLP_SYMBOL64;
+
+ typedef struct _IMAGEHLP_SYMBOL64_PACKAGE {
+ IMAGEHLP_SYMBOL64 sym;
+ CHAR name[MAX_SYM_NAME + 1];
+ } IMAGEHLP_SYMBOL64_PACKAGE,*PIMAGEHLP_SYMBOL64_PACKAGE;
+
+#ifdef _IMAGEHLP64
+
+#define IMAGEHLP_SYMBOL IMAGEHLP_SYMBOL64
+#define PIMAGEHLP_SYMBOL PIMAGEHLP_SYMBOL64
+#define IMAGEHLP_SYMBOL_PACKAGE IMAGEHLP_SYMBOL64_PACKAGE
+#define PIMAGEHLP_SYMBOL_PACKAGE PIMAGEHLP_SYMBOL64_PACKAGE
+#else
+
+ typedef struct _IMAGEHLP_SYMBOL {
+ DWORD SizeOfStruct;
+ DWORD Address;
+ DWORD Size;
+ DWORD Flags;
+ DWORD MaxNameLength;
+ CHAR Name[1];
+ } IMAGEHLP_SYMBOL,*PIMAGEHLP_SYMBOL;
+
+ typedef struct _IMAGEHLP_SYMBOL_PACKAGE {
+ IMAGEHLP_SYMBOL sym;
+ CHAR name[MAX_SYM_NAME + 1];
+ } IMAGEHLP_SYMBOL_PACKAGE,*PIMAGEHLP_SYMBOL_PACKAGE;
+#endif
+
+ typedef struct _IMAGEHLP_MODULE64 {
+ DWORD SizeOfStruct;
+ DWORD64 BaseOfImage;
+ DWORD ImageSize;
+ DWORD TimeDateStamp;
+ DWORD CheckSum;
+ DWORD NumSyms;
+ SYM_TYPE SymType;
+ CHAR ModuleName[32];
+ CHAR ImageName[256];
+ CHAR LoadedImageName[256];
+ CHAR LoadedPdbName[256];
+ DWORD CVSig;
+ CHAR CVData[MAX_PATH*3];
+ DWORD PdbSig;
+ GUID PdbSig70;
+ DWORD PdbAge;
+ BOOL PdbUnmatched;
+ BOOL DbgUnmatched;
+ BOOL LineNumbers;
+ BOOL GlobalSymbols;
+ BOOL TypeInfo;
+ } IMAGEHLP_MODULE64,*PIMAGEHLP_MODULE64;
+
+ typedef struct _IMAGEHLP_MODULE64W {
+ DWORD SizeOfStruct;
+ DWORD64 BaseOfImage;
+ DWORD ImageSize;
+ DWORD TimeDateStamp;
+ DWORD CheckSum;
+ DWORD NumSyms;
+ SYM_TYPE SymType;
+ WCHAR ModuleName[32];
+ WCHAR ImageName[256];
+ WCHAR LoadedImageName[256];
+ WCHAR LoadedPdbName[256];
+ DWORD CVSig;
+ WCHAR CVData[MAX_PATH*3];
+ DWORD PdbSig;
+ GUID PdbSig70;
+ DWORD PdbAge;
+ BOOL PdbUnmatched;
+ BOOL DbgUnmatched;
+ BOOL LineNumbers;
+ BOOL GlobalSymbols;
+ BOOL TypeInfo;
+ } IMAGEHLP_MODULEW64,*PIMAGEHLP_MODULEW64;
+
+#ifdef _IMAGEHLP64
+#define IMAGEHLP_MODULE IMAGEHLP_MODULE64
+#define PIMAGEHLP_MODULE PIMAGEHLP_MODULE64
+#define IMAGEHLP_MODULEW IMAGEHLP_MODULEW64
+#define PIMAGEHLP_MODULEW PIMAGEHLP_MODULEW64
+#else
+ typedef struct _IMAGEHLP_MODULE {
+ DWORD SizeOfStruct;
+ DWORD BaseOfImage;
+ DWORD ImageSize;
+ DWORD TimeDateStamp;
+ DWORD CheckSum;
+ DWORD NumSyms;
+ SYM_TYPE SymType;
+ CHAR ModuleName[32];
+ CHAR ImageName[256];
+ CHAR LoadedImageName[256];
+ } IMAGEHLP_MODULE,*PIMAGEHLP_MODULE;
+
+ typedef struct _IMAGEHLP_MODULEW {
+ DWORD SizeOfStruct;
+ DWORD BaseOfImage;
+ DWORD ImageSize;
+ DWORD TimeDateStamp;
+ DWORD CheckSum;
+ DWORD NumSyms;
+ SYM_TYPE SymType;
+ WCHAR ModuleName[32];
+ WCHAR ImageName[256];
+ WCHAR LoadedImageName[256];
+ } IMAGEHLP_MODULEW,*PIMAGEHLP_MODULEW;
+#endif
+
+ typedef struct _IMAGEHLP_LINE64 {
+ DWORD SizeOfStruct;
+ PVOID Key;
+ DWORD LineNumber;
+ PCHAR FileName;
+ DWORD64 Address;
+ } IMAGEHLP_LINE64,*PIMAGEHLP_LINE64;
+
+#ifdef _IMAGEHLP64
+#define IMAGEHLP_LINE IMAGEHLP_LINE64
+#define PIMAGEHLP_LINE PIMAGEHLP_LINE64
+#else
+ typedef struct _IMAGEHLP_LINE {
+ DWORD SizeOfStruct;
+ PVOID Key;
+ DWORD LineNumber;
+ PCHAR FileName;
+ DWORD Address;
+ } IMAGEHLP_LINE,*PIMAGEHLP_LINE;
+#endif
+
+ typedef struct _SOURCEFILE {
+ DWORD64 ModBase;
+ PCHAR FileName;
+ } SOURCEFILE,*PSOURCEFILE;
+
+#define CBA_DEFERRED_SYMBOL_LOAD_START 0x00000001
+#define CBA_DEFERRED_SYMBOL_LOAD_COMPLETE 0x00000002
+#define CBA_DEFERRED_SYMBOL_LOAD_FAILURE 0x00000003
+#define CBA_SYMBOLS_UNLOADED 0x00000004
+#define CBA_DUPLICATE_SYMBOL 0x00000005
+#define CBA_READ_MEMORY 0x00000006
+#define CBA_DEFERRED_SYMBOL_LOAD_CANCEL 0x00000007
+#define CBA_SET_OPTIONS 0x00000008
+#define CBA_EVENT 0x00000010
+#define CBA_DEFERRED_SYMBOL_LOAD_PARTIAL 0x00000020
+#define CBA_DEBUG_INFO 0x10000000
+
+ typedef struct _IMAGEHLP_CBA_READ_MEMORY {
+ DWORD64 addr;
+ PVOID buf;
+ DWORD bytes;
+ DWORD *bytesread;
+ } IMAGEHLP_CBA_READ_MEMORY,*PIMAGEHLP_CBA_READ_MEMORY;
+
+ enum {
+ sevInfo = 0,sevProblem,sevAttn,sevFatal,sevMax
+ };
+
+ typedef struct _IMAGEHLP_CBA_EVENT {
+ DWORD severity;
+ DWORD code;
+ PCHAR desc;
+ PVOID object;
+ } IMAGEHLP_CBA_EVENT,*PIMAGEHLP_CBA_EVENT;
+
+ typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD64 {
+ DWORD SizeOfStruct;
+ DWORD64 BaseOfImage;
+ DWORD CheckSum;
+ DWORD TimeDateStamp;
+ CHAR FileName[MAX_PATH];
+ BOOLEAN Reparse;
+ HANDLE hFile;
+ DWORD Flags;
+ } IMAGEHLP_DEFERRED_SYMBOL_LOAD64,*PIMAGEHLP_DEFERRED_SYMBOL_LOAD64;
+
+#define DSLFLAG_MISMATCHED_PDB 0x1
+#define DSLFLAG_MISMATCHED_DBG 0x2
+
+#ifdef _IMAGEHLP64
+#define IMAGEHLP_DEFERRED_SYMBOL_LOAD IMAGEHLP_DEFERRED_SYMBOL_LOAD64
+#define PIMAGEHLP_DEFERRED_SYMBOL_LOAD PIMAGEHLP_DEFERRED_SYMBOL_LOAD64
+#else
+ typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD {
+ DWORD SizeOfStruct;
+ DWORD BaseOfImage;
+ DWORD CheckSum;
+ DWORD TimeDateStamp;
+ CHAR FileName[MAX_PATH];
+ BOOLEAN Reparse;
+ HANDLE hFile;
+ } IMAGEHLP_DEFERRED_SYMBOL_LOAD,*PIMAGEHLP_DEFERRED_SYMBOL_LOAD;
+#endif
+
+ typedef struct _IMAGEHLP_DUPLICATE_SYMBOL64 {
+ DWORD SizeOfStruct;
+ DWORD NumberOfDups;
+ PIMAGEHLP_SYMBOL64 Symbol;
+ DWORD SelectedSymbol;
+ } IMAGEHLP_DUPLICATE_SYMBOL64,*PIMAGEHLP_DUPLICATE_SYMBOL64;
+
+#ifdef _IMAGEHLP64
+#define IMAGEHLP_DUPLICATE_SYMBOL IMAGEHLP_DUPLICATE_SYMBOL64
+#define PIMAGEHLP_DUPLICATE_SYMBOL PIMAGEHLP_DUPLICATE_SYMBOL64
+#else
+ typedef struct _IMAGEHLP_DUPLICATE_SYMBOL {
+ DWORD SizeOfStruct;
+ DWORD NumberOfDups;
+ PIMAGEHLP_SYMBOL Symbol;
+ DWORD SelectedSymbol;
+ } IMAGEHLP_DUPLICATE_SYMBOL,*PIMAGEHLP_DUPLICATE_SYMBOL;
+#endif
+
+ BOOL IMAGEAPI SymSetParentWindow(HWND hwnd);
+ PCHAR IMAGEAPI SymSetHomeDirectory(PCSTR dir);
+ PCHAR IMAGEAPI SymGetHomeDirectory(DWORD type,PSTR dir,size_t size);
+
+ enum {
+ hdBase = 0,hdSym,hdSrc,hdMax
+ };
+
+#define SYMOPT_CASE_INSENSITIVE 0x00000001
+#define SYMOPT_UNDNAME 0x00000002
+#define SYMOPT_DEFERRED_LOADS 0x00000004
+#define SYMOPT_NO_CPP 0x00000008
+#define SYMOPT_LOAD_LINES 0x00000010
+#define SYMOPT_OMAP_FIND_NEAREST 0x00000020
+#define SYMOPT_LOAD_ANYTHING 0x00000040
+#define SYMOPT_IGNORE_CVREC 0x00000080
+#define SYMOPT_NO_UNQUALIFIED_LOADS 0x00000100
+#define SYMOPT_FAIL_CRITICAL_ERRORS 0x00000200
+#define SYMOPT_EXACT_SYMBOLS 0x00000400
+#define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS 0x00000800
+#define SYMOPT_IGNORE_NT_SYMPATH 0x00001000
+#define SYMOPT_INCLUDE_32BIT_MODULES 0x00002000
+#define SYMOPT_PUBLICS_ONLY 0x00004000
+#define SYMOPT_NO_PUBLICS 0x00008000
+#define SYMOPT_AUTO_PUBLICS 0x00010000
+#define SYMOPT_NO_IMAGE_SEARCH 0x00020000
+#define SYMOPT_SECURE 0x00040000
+#define SYMOPT_NO_PROMPTS 0x00080000
+
+#define SYMOPT_DEBUG 0x80000000
+
+ DWORD IMAGEAPI SymSetOptions(DWORD SymOptions);
+ DWORD IMAGEAPI SymGetOptions(VOID);
+ BOOL IMAGEAPI SymCleanup(HANDLE hProcess);
+ BOOL IMAGEAPI SymMatchString(LPSTR string,LPSTR expression,BOOL fCase);
+
+ typedef BOOL (CALLBACK *PSYM_ENUMSOURCFILES_CALLBACK)(PSOURCEFILE pSourceFile,PVOID UserContext);
+
+ BOOL IMAGEAPI SymEnumSourceFiles(HANDLE hProcess,ULONG64 ModBase,LPSTR Mask,PSYM_ENUMSOURCFILES_CALLBACK cbSrcFiles,PVOID UserContext);
+ BOOL IMAGEAPI SymEnumerateModules64(HANDLE hProcess,PSYM_ENUMMODULES_CALLBACK64 EnumModulesCallback,PVOID UserContext);
+
+#ifdef _IMAGEHLP64
+#define SymEnumerateModules SymEnumerateModules64
+#else
+ BOOL IMAGEAPI SymEnumerateModules(HANDLE hProcess,PSYM_ENUMMODULES_CALLBACK EnumModulesCallback,PVOID UserContext);
+#endif
+
+ BOOL IMAGEAPI SymEnumerateSymbols64(HANDLE hProcess,DWORD64 BaseOfDll,PSYM_ENUMSYMBOLS_CALLBACK64 EnumSymbolsCallback,PVOID UserContext);
+ BOOL IMAGEAPI SymEnumerateSymbolsW64(HANDLE hProcess,DWORD64 BaseOfDll,PSYM_ENUMSYMBOLS_CALLBACK64W EnumSymbolsCallback,PVOID UserContext);
+
+#ifdef _IMAGEHLP64
+#define SymEnumerateSymbols SymEnumerateSymbols64
+#define SymEnumerateSymbolsW SymEnumerateSymbolsW64
+#else
+ BOOL IMAGEAPI SymEnumerateSymbols(HANDLE hProcess,DWORD BaseOfDll,PSYM_ENUMSYMBOLS_CALLBACK EnumSymbolsCallback,PVOID UserContext);
+ BOOL IMAGEAPI SymEnumerateSymbolsW(HANDLE hProcess,DWORD BaseOfDll,PSYM_ENUMSYMBOLS_CALLBACKW EnumSymbolsCallback,PVOID UserContext);
+#endif
+
+ BOOL IMAGEAPI EnumerateLoadedModules64(HANDLE hProcess,PENUMLOADED_MODULES_CALLBACK64 EnumLoadedModulesCallback,PVOID UserContext);
+#ifdef _IMAGEHLP64
+#define EnumerateLoadedModules EnumerateLoadedModules64
+#else
+ BOOL IMAGEAPI EnumerateLoadedModules(HANDLE hProcess,PENUMLOADED_MODULES_CALLBACK EnumLoadedModulesCallback,PVOID UserContext);
+#endif
+
+ PVOID IMAGEAPI SymFunctionTableAccess64(HANDLE hProcess,DWORD64 AddrBase);
+
+#ifdef _IMAGEHLP64
+#define SymFunctionTableAccess SymFunctionTableAccess64
+#else
+ PVOID IMAGEAPI SymFunctionTableAccess(HANDLE hProcess,DWORD AddrBase);
+#endif
+
+ BOOL IMAGEAPI SymGetModuleInfo64(HANDLE hProcess,DWORD64 qwAddr,PIMAGEHLP_MODULE64 ModuleInfo);
+ BOOL IMAGEAPI SymGetModuleInfoW64(HANDLE hProcess,DWORD64 qwAddr,PIMAGEHLP_MODULEW64 ModuleInfo);
+
+#ifdef _IMAGEHLP64
+#define SymGetModuleInfo SymGetModuleInfo64
+#define SymGetModuleInfoW SymGetModuleInfoW64
+#else
+ BOOL IMAGEAPI SymGetModuleInfo(HANDLE hProcess,DWORD dwAddr,PIMAGEHLP_MODULE ModuleInfo);
+ BOOL IMAGEAPI SymGetModuleInfoW(HANDLE hProcess,DWORD dwAddr,PIMAGEHLP_MODULEW ModuleInfo);
+#endif
+
+ DWORD64 IMAGEAPI SymGetModuleBase64(HANDLE hProcess,DWORD64 qwAddr);
+
+#ifdef _IMAGEHLP64
+#define SymGetModuleBase SymGetModuleBase64
+#else
+ DWORD IMAGEAPI SymGetModuleBase(HANDLE hProcess,DWORD dwAddr);
+#endif
+
+ BOOL IMAGEAPI SymGetSymNext64(HANDLE hProcess,PIMAGEHLP_SYMBOL64 Symbol);
+
+#ifdef _IMAGEHLP64
+#define SymGetSymNext SymGetSymNext64
+#else
+ BOOL IMAGEAPI SymGetSymNext(HANDLE hProcess,PIMAGEHLP_SYMBOL Symbol);
+#endif
+
+ BOOL IMAGEAPI SymGetSymPrev64(HANDLE hProcess,PIMAGEHLP_SYMBOL64 Symbol);
+
+#ifdef _IMAGEHLP64
+#define SymGetSymPrev SymGetSymPrev64
+#else
+ BOOL IMAGEAPI SymGetSymPrev(HANDLE hProcess,PIMAGEHLP_SYMBOL Symbol);
+#endif
+
+ typedef struct _SRCCODEINFO {
+ DWORD SizeOfStruct;
+ PVOID Key;
+ DWORD64 ModBase;
+ CHAR Obj[MAX_PATH + 1];
+ CHAR FileName[MAX_PATH + 1];
+ DWORD LineNumber;
+ DWORD64 Address;
+ } SRCCODEINFO,*PSRCCODEINFO;
+
+ typedef BOOL (CALLBACK *PSYM_ENUMLINES_CALLBACK)(PSRCCODEINFO LineInfo,PVOID UserContext);
+
+ BOOL IMAGEAPI SymEnumLines(HANDLE hProcess,ULONG64 Base,PCSTR Obj,PCSTR File,PSYM_ENUMLINES_CALLBACK EnumLinesCallback,PVOID UserContext);
+ BOOL IMAGEAPI SymGetLineFromAddr64(HANDLE hProcess,DWORD64 qwAddr,PDWORD pdwDisplacement,PIMAGEHLP_LINE64 Line64);
+
+#ifdef _IMAGEHLP64
+#define SymGetLineFromAddr SymGetLineFromAddr64
+#else
+ BOOL IMAGEAPI SymGetLineFromAddr(HANDLE hProcess,DWORD dwAddr,PDWORD pdwDisplacement,PIMAGEHLP_LINE Line);
+#endif
+
+ BOOL IMAGEAPI SymGetLineFromName64(HANDLE hProcess,PSTR ModuleName,PSTR FileName,DWORD dwLineNumber,PLONG plDisplacement,PIMAGEHLP_LINE64 Line);
+
+#ifdef _IMAGEHLP64
+#define SymGetLineFromName SymGetLineFromName64
+#else
+ BOOL IMAGEAPI SymGetLineFromName(HANDLE hProcess,PSTR ModuleName,PSTR FileName,DWORD dwLineNumber,PLONG plDisplacement,PIMAGEHLP_LINE Line);
+#endif
+
+ BOOL IMAGEAPI SymGetLineNext64(HANDLE hProcess,PIMAGEHLP_LINE64 Line);
+
+#ifdef _IMAGEHLP64
+#define SymGetLineNext SymGetLineNext64
+#else
+ BOOL IMAGEAPI SymGetLineNext(HANDLE hProcess,PIMAGEHLP_LINE Line);
+#endif
+
+ BOOL IMAGEAPI SymGetLinePrev64(HANDLE hProcess,PIMAGEHLP_LINE64 Line);
+
+#ifdef _IMAGEHLP64
+#define SymGetLinePrev SymGetLinePrev64
+#else
+ BOOL IMAGEAPI SymGetLinePrev(HANDLE hProcess,PIMAGEHLP_LINE Line);
+#endif
+
+ BOOL IMAGEAPI SymMatchFileName(PSTR FileName,PSTR Match,PSTR *FileNameStop,PSTR *MatchStop);
+ BOOL IMAGEAPI SymInitialize(HANDLE hProcess,PSTR UserSearchPath,BOOL fInvadeProcess);
+ BOOL IMAGEAPI SymGetSearchPath(HANDLE hProcess,PSTR SearchPath,DWORD SearchPathLength);
+ BOOL IMAGEAPI SymSetSearchPath(HANDLE hProcess,PSTR SearchPath);
+ DWORD64 IMAGEAPI SymLoadModule64(HANDLE hProcess,HANDLE hFile,PSTR ImageName,PSTR ModuleName,DWORD64 BaseOfDll,DWORD SizeOfDll);
+
+#define SLMFLAG_VIRTUAL 0x1
+
+ DWORD64 IMAGEAPI SymLoadModuleEx(HANDLE hProcess,HANDLE hFile,PSTR ImageName,PSTR ModuleName,DWORD64 BaseOfDll,DWORD DllSize,PMODLOAD_DATA Data,DWORD Flags);
+
+#ifdef _IMAGEHLP64
+#define SymLoadModule SymLoadModule64
+#else
+ DWORD IMAGEAPI SymLoadModule(HANDLE hProcess,HANDLE hFile,PSTR ImageName,PSTR ModuleName,DWORD BaseOfDll,DWORD SizeOfDll);
+#endif
+
+ BOOL IMAGEAPI SymUnloadModule64(HANDLE hProcess,DWORD64 BaseOfDll);
+
+#ifdef _IMAGEHLP64
+#define SymUnloadModule SymUnloadModule64
+#else
+ BOOL IMAGEAPI SymUnloadModule(HANDLE hProcess,DWORD BaseOfDll);
+#endif
+
+ BOOL IMAGEAPI SymUnDName64(PIMAGEHLP_SYMBOL64 sym,PSTR UnDecName,DWORD UnDecNameLength);
+
+#ifdef _IMAGEHLP64
+#define SymUnDName SymUnDName64
+#else
+ BOOL IMAGEAPI SymUnDName(PIMAGEHLP_SYMBOL sym,PSTR UnDecName,DWORD UnDecNameLength);
+#endif
+
+ BOOL IMAGEAPI SymRegisterCallback64(HANDLE hProcess,PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction,ULONG64 UserContext);
+
+ BOOL IMAGEAPI SymRegisterFunctionEntryCallback64(HANDLE hProcess,PSYMBOL_FUNCENTRY_CALLBACK64 CallbackFunction,ULONG64 UserContext);
+
+#ifdef _IMAGEHLP64
+#define SymRegisterCallback SymRegisterCallback64
+#define SymRegisterFunctionEntryCallback SymRegisterFunctionEntryCallback64
+#else
+ BOOL IMAGEAPI SymRegisterCallback(HANDLE hProcess,PSYMBOL_REGISTERED_CALLBACK CallbackFunction,PVOID UserContext);
+ BOOL IMAGEAPI SymRegisterFunctionEntryCallback(HANDLE hProcess,PSYMBOL_FUNCENTRY_CALLBACK CallbackFunction,PVOID UserContext);
+#endif
+
+ typedef struct _IMAGEHLP_SYMBOL_SRC {
+ DWORD sizeofstruct;
+ DWORD type;
+ char file[MAX_PATH];
+ } IMAGEHLP_SYMBOL_SRC,*PIMAGEHLP_SYMBOL_SRC;
+
+ typedef struct _MODULE_TYPE_INFO {
+ USHORT dataLength;
+ USHORT leaf;
+ BYTE data[1];
+ } MODULE_TYPE_INFO,*PMODULE_TYPE_INFO;
+
+ typedef struct _SYMBOL_INFO {
+ ULONG SizeOfStruct;
+ ULONG TypeIndex;
+ ULONG64 Reserved[2];
+ ULONG info;
+ ULONG Size;
+ ULONG64 ModBase;
+ ULONG Flags;
+ ULONG64 Value;
+ ULONG64 Address;
+ ULONG Register;
+ ULONG Scope;
+ ULONG Tag;
+ ULONG NameLen;
+ ULONG MaxNameLen;
+ CHAR Name[1];
+ } SYMBOL_INFO,*PSYMBOL_INFO;
+
+ typedef struct _SYMBOL_INFO_PACKAGE {
+ SYMBOL_INFO si;
+ CHAR name[MAX_SYM_NAME + 1];
+ } SYMBOL_INFO_PACKAGE,*PSYMBOL_INFO_PACKAGE;
+
+ typedef struct _IMAGEHLP_STACK_FRAME
+ {
+ ULONG64 InstructionOffset;
+ ULONG64 ReturnOffset;
+ ULONG64 FrameOffset;
+ ULONG64 StackOffset;
+ ULONG64 BackingStoreOffset;
+ ULONG64 FuncTableEntry;
+ ULONG64 Params[4];
+ ULONG64 Reserved[5];
+ BOOL Virtual;
+ ULONG Reserved2;
+ } IMAGEHLP_STACK_FRAME,*PIMAGEHLP_STACK_FRAME;
+
+ typedef VOID IMAGEHLP_CONTEXT,*PIMAGEHLP_CONTEXT;
+
+ BOOL IMAGEAPI SymSetContext(HANDLE hProcess,PIMAGEHLP_STACK_FRAME StackFrame,PIMAGEHLP_CONTEXT Context);
+ BOOL IMAGEAPI SymFromAddr(HANDLE hProcess,DWORD64 Address,PDWORD64 Displacement,PSYMBOL_INFO Symbol);
+ BOOL IMAGEAPI SymFromToken(HANDLE hProcess,DWORD64 Base,DWORD Token,PSYMBOL_INFO Symbol);
+ BOOL IMAGEAPI SymFromName(HANDLE hProcess,LPSTR Name,PSYMBOL_INFO Symbol);
+
+ typedef BOOL (CALLBACK *PSYM_ENUMERATESYMBOLS_CALLBACK)(PSYMBOL_INFO pSymInfo,ULONG SymbolSize,PVOID UserContext);
+
+ BOOL IMAGEAPI SymEnumSymbols(HANDLE hProcess,ULONG64 BaseOfDll,PCSTR Mask,PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,PVOID UserContext);
+ BOOL IMAGEAPI SymEnumSymbolsForAddr(HANDLE hProcess,DWORD64 Address,PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,PVOID UserContext);
+
+#define SYMENUMFLAG_FULLSRCH 1
+#define SYMENUMFLAG_SPEEDSRCH 2
+
+ typedef enum _IMAGEHLP_SYMBOL_TYPE_INFO {
+ TI_GET_SYMTAG,TI_GET_SYMNAME,TI_GET_LENGTH,TI_GET_TYPE,TI_GET_TYPEID,TI_GET_BASETYPE,TI_GET_ARRAYINDEXTYPEID,TI_FINDCHILDREN,
+ TI_GET_DATAKIND,TI_GET_ADDRESSOFFSET,TI_GET_OFFSET,TI_GET_VALUE,TI_GET_COUNT,TI_GET_CHILDRENCOUNT,TI_GET_BITPOSITION,TI_GET_VIRTUALBASECLASS,
+ TI_GET_VIRTUALTABLESHAPEID,TI_GET_VIRTUALBASEPOINTEROFFSET,TI_GET_CLASSPARENTID,TI_GET_NESTED,TI_GET_SYMINDEX,TI_GET_LEXICALPARENT,
+ TI_GET_ADDRESS,TI_GET_THISADJUST,TI_GET_UDTKIND,TI_IS_EQUIV_TO,TI_GET_CALLING_CONVENTION
+ } IMAGEHLP_SYMBOL_TYPE_INFO;
+
+ typedef struct _TI_FINDCHILDREN_PARAMS {
+ ULONG Count;
+ ULONG Start;
+ ULONG ChildId[1];
+ } TI_FINDCHILDREN_PARAMS;
+
+ BOOL IMAGEAPI SymGetTypeInfo(HANDLE hProcess,DWORD64 ModBase,ULONG TypeId,IMAGEHLP_SYMBOL_TYPE_INFO GetType,PVOID pInfo);
+ BOOL IMAGEAPI SymEnumTypes(HANDLE hProcess,ULONG64 BaseOfDll,PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,PVOID UserContext);
+ BOOL IMAGEAPI SymGetTypeFromName(HANDLE hProcess,ULONG64 BaseOfDll,LPSTR Name,PSYMBOL_INFO Symbol);
+ BOOL IMAGEAPI SymAddSymbol(HANDLE hProcess,ULONG64 BaseOfDll,PCSTR Name,DWORD64 Address,DWORD Size,DWORD Flags);
+ BOOL IMAGEAPI SymDeleteSymbol(HANDLE hProcess,ULONG64 BaseOfDll,PCSTR Name,DWORD64 Address,DWORD Flags);
+
+ typedef BOOL (WINAPI *PDBGHELP_CREATE_USER_DUMP_CALLBACK)(DWORD DataType,PVOID *Data,LPDWORD DataLength,PVOID UserData);
+
+ BOOL WINAPI DbgHelpCreateUserDump(LPSTR FileName,PDBGHELP_CREATE_USER_DUMP_CALLBACK Callback,PVOID UserData);
+ BOOL WINAPI DbgHelpCreateUserDumpW(LPWSTR FileName,PDBGHELP_CREATE_USER_DUMP_CALLBACK Callback,PVOID UserData);
+ BOOL IMAGEAPI SymGetSymFromAddr64(HANDLE hProcess,DWORD64 qwAddr,PDWORD64 pdwDisplacement,PIMAGEHLP_SYMBOL64 Symbol);
+
+#ifdef _IMAGEHLP64
+#define SymGetSymFromAddr SymGetSymFromAddr64
+#else
+ BOOL IMAGEAPI SymGetSymFromAddr(HANDLE hProcess,DWORD dwAddr,PDWORD pdwDisplacement,PIMAGEHLP_SYMBOL Symbol);
+#endif
+
+ BOOL IMAGEAPI SymGetSymFromName64(HANDLE hProcess,PSTR Name,PIMAGEHLP_SYMBOL64 Symbol);
+
+#ifdef _IMAGEHLP64
+#define SymGetSymFromName SymGetSymFromName64
+#else
+ BOOL IMAGEAPI SymGetSymFromName(HANDLE hProcess,PSTR Name,PIMAGEHLP_SYMBOL Symbol);
+#endif
+
+ DBHLP_DEPRECIATED BOOL IMAGEAPI FindFileInPath(HANDLE hprocess,LPSTR SearchPath,LPSTR FileName,PVOID id,DWORD two,DWORD three,DWORD flags,LPSTR FilePath);
+ DBHLP_DEPRECIATED BOOL IMAGEAPI FindFileInSearchPath(HANDLE hprocess,LPSTR SearchPath,LPSTR FileName,DWORD one,DWORD two,DWORD three,LPSTR FilePath);
+ DBHLP_DEPRECIATED BOOL IMAGEAPI SymEnumSym(HANDLE hProcess,ULONG64 BaseOfDll,PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,PVOID UserContext);
+
+#define SYMF_OMAP_GENERATED 0x00000001
+#define SYMF_OMAP_MODIFIED 0x00000002
+#define SYMF_REGISTER 0x00000008
+#define SYMF_REGREL 0x00000010
+#define SYMF_FRAMEREL 0x00000020
+#define SYMF_PARAMETER 0x00000040
+#define SYMF_LOCAL 0x00000080
+#define SYMF_CONSTANT 0x00000100
+#define SYMF_EXPORT 0x00000200
+#define SYMF_FORWARDER 0x00000400
+#define SYMF_FUNCTION 0x00000800
+#define SYMF_VIRTUAL 0x00001000
+#define SYMF_THUNK 0x00002000
+#define SYMF_TLSREL 0x00004000
+
+#define IMAGEHLP_SYMBOL_INFO_VALUEPRESENT 1
+#define IMAGEHLP_SYMBOL_INFO_REGISTER SYMF_REGISTER
+#define IMAGEHLP_SYMBOL_INFO_REGRELATIVE SYMF_REGREL
+#define IMAGEHLP_SYMBOL_INFO_FRAMERELATIVE SYMF_FRAMEREL
+#define IMAGEHLP_SYMBOL_INFO_PARAMETER SYMF_PARAMETER
+#define IMAGEHLP_SYMBOL_INFO_LOCAL SYMF_LOCAL
+#define IMAGEHLP_SYMBOL_INFO_CONSTANT SYMF_CONSTANT
+#define IMAGEHLP_SYMBOL_FUNCTION SYMF_FUNCTION
+#define IMAGEHLP_SYMBOL_VIRTUAL SYMF_VIRTUAL
+#define IMAGEHLP_SYMBOL_THUNK SYMF_THUNK
+#define IMAGEHLP_SYMBOL_INFO_TLSRELATIVE SYMF_TLSREL
+
+#include <pshpack4.h>
+
+#define MINIDUMP_SIGNATURE ('PMDM')
+#define MINIDUMP_VERSION (42899)
+ typedef DWORD RVA;
+ typedef ULONG64 RVA64;
+
+ typedef struct _MINIDUMP_LOCATION_DESCRIPTOR {
+ ULONG32 DataSize;
+ RVA Rva;
+ } MINIDUMP_LOCATION_DESCRIPTOR;
+
+ typedef struct _MINIDUMP_LOCATION_DESCRIPTOR64 {
+ ULONG64 DataSize;
+ RVA64 Rva;
+ } MINIDUMP_LOCATION_DESCRIPTOR64;
+
+ typedef struct _MINIDUMP_MEMORY_DESCRIPTOR {
+ ULONG64 StartOfMemoryRange;
+ MINIDUMP_LOCATION_DESCRIPTOR Memory;
+ } MINIDUMP_MEMORY_DESCRIPTOR,*PMINIDUMP_MEMORY_DESCRIPTOR;
+
+ typedef struct _MINIDUMP_MEMORY_DESCRIPTOR64 {
+ ULONG64 StartOfMemoryRange;
+ ULONG64 DataSize;
+ } MINIDUMP_MEMORY_DESCRIPTOR64,*PMINIDUMP_MEMORY_DESCRIPTOR64;
+
+ typedef struct _MINIDUMP_HEADER {
+ ULONG32 Signature;
+ ULONG32 Version;
+ ULONG32 NumberOfStreams;
+ RVA StreamDirectoryRva;
+ ULONG32 CheckSum;
+ union {
+ ULONG32 Reserved;
+ ULONG32 TimeDateStamp;
+ } DUMMYUNIONNAME;
+ ULONG64 Flags;
+ } MINIDUMP_HEADER,*PMINIDUMP_HEADER;
+
+ typedef struct _MINIDUMP_DIRECTORY {
+ ULONG32 StreamType;
+ MINIDUMP_LOCATION_DESCRIPTOR Location;
+ } MINIDUMP_DIRECTORY,*PMINIDUMP_DIRECTORY;
+
+ typedef struct _MINIDUMP_STRING {
+ ULONG32 Length;
+ WCHAR Buffer [0];
+ } MINIDUMP_STRING,*PMINIDUMP_STRING;
+
+ typedef enum _MINIDUMP_STREAM_TYPE {
+ UnusedStream = 0,ReservedStream0 = 1,ReservedStream1 = 2,ThreadListStream = 3,ModuleListStream = 4,MemoryListStream = 5,
+ ExceptionStream = 6,SystemInfoStream = 7,ThreadExListStream = 8,Memory64ListStream = 9,CommentStreamA = 10,CommentStreamW = 11,
+ HandleDataStream = 12,FunctionTableStream = 13,UnloadedModuleListStream = 14,MiscInfoStream = 15,LastReservedStream = 0xffff
+ } MINIDUMP_STREAM_TYPE;
+
+ typedef union _CPU_INFORMATION {
+ struct {
+ ULONG32 VendorId [3 ];
+ ULONG32 VersionInformation;
+ ULONG32 FeatureInformation;
+ ULONG32 AMDExtendedCpuFeatures;
+ } X86CpuInfo;
+ struct {
+ ULONG64 ProcessorFeatures [2 ];
+ } OtherCpuInfo;
+ } CPU_INFORMATION,*PCPU_INFORMATION;
+
+ typedef struct _MINIDUMP_SYSTEM_INFO {
+ USHORT ProcessorArchitecture;
+ USHORT ProcessorLevel;
+ USHORT ProcessorRevision;
+ union {
+ USHORT Reserved0;
+ struct {
+ UCHAR NumberOfProcessors;
+ UCHAR ProductType;
+ } DUMMYSTRUCTNAME;
+ } DUMMYUNIONNAME;
+ ULONG32 MajorVersion;
+ ULONG32 MinorVersion;
+ ULONG32 BuildNumber;
+ ULONG32 PlatformId;
+ RVA CSDVersionRva;
+ union {
+ ULONG32 Reserved1;
+ struct {
+ USHORT SuiteMask;
+ USHORT Reserved2;
+ } DUMMYSTRUCTNAME;
+ } DUMMYUNIONNAME1;
+ CPU_INFORMATION Cpu;
+ } MINIDUMP_SYSTEM_INFO,*PMINIDUMP_SYSTEM_INFO;
+
+ C_ASSERT (sizeof (((PPROCESS_INFORMATION)0)->dwThreadId)==4);
+
+ typedef struct _MINIDUMP_THREAD {
+ ULONG32 ThreadId;
+ ULONG32 SuspendCount;
+ ULONG32 PriorityClass;
+ ULONG32 Priority;
+ ULONG64 Teb;
+ MINIDUMP_MEMORY_DESCRIPTOR Stack;
+ MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;
+ } MINIDUMP_THREAD,*PMINIDUMP_THREAD;
+
+ typedef struct _MINIDUMP_THREAD_LIST {
+ ULONG32 NumberOfThreads;
+ MINIDUMP_THREAD Threads [0];
+ } MINIDUMP_THREAD_LIST,*PMINIDUMP_THREAD_LIST;
+
+ typedef struct _MINIDUMP_THREAD_EX {
+ ULONG32 ThreadId;
+ ULONG32 SuspendCount;
+ ULONG32 PriorityClass;
+ ULONG32 Priority;
+ ULONG64 Teb;
+ MINIDUMP_MEMORY_DESCRIPTOR Stack;
+ MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;
+ MINIDUMP_MEMORY_DESCRIPTOR BackingStore;
+ } MINIDUMP_THREAD_EX,*PMINIDUMP_THREAD_EX;
+
+ typedef struct _MINIDUMP_THREAD_EX_LIST {
+ ULONG32 NumberOfThreads;
+ MINIDUMP_THREAD_EX Threads [0];
+ } MINIDUMP_THREAD_EX_LIST,*PMINIDUMP_THREAD_EX_LIST;
+
+ typedef struct _MINIDUMP_EXCEPTION {
+ ULONG32 ExceptionCode;
+ ULONG32 ExceptionFlags;
+ ULONG64 ExceptionRecord;
+ ULONG64 ExceptionAddress;
+ ULONG32 NumberParameters;
+ ULONG32 __unusedAlignment;
+ ULONG64 ExceptionInformation [EXCEPTION_MAXIMUM_PARAMETERS ];
+ } MINIDUMP_EXCEPTION,*PMINIDUMP_EXCEPTION;
+
+ typedef struct MINIDUMP_EXCEPTION_STREAM {
+ ULONG32 ThreadId;
+ ULONG32 __alignment;
+ MINIDUMP_EXCEPTION ExceptionRecord;
+ MINIDUMP_LOCATION_DESCRIPTOR ThreadContext;
+ } MINIDUMP_EXCEPTION_STREAM,*PMINIDUMP_EXCEPTION_STREAM;
+
+ typedef struct _MINIDUMP_MODULE {
+ ULONG64 BaseOfImage;
+ ULONG32 SizeOfImage;
+ ULONG32 CheckSum;
+ ULONG32 TimeDateStamp;
+ RVA ModuleNameRva;
+ VS_FIXEDFILEINFO VersionInfo;
+ MINIDUMP_LOCATION_DESCRIPTOR CvRecord;
+ MINIDUMP_LOCATION_DESCRIPTOR MiscRecord;
+ ULONG64 Reserved0;
+ ULONG64 Reserved1;
+ } MINIDUMP_MODULE,*PMINIDUMP_MODULE;
+
+ typedef struct _MINIDUMP_MODULE_LIST {
+ ULONG32 NumberOfModules;
+ MINIDUMP_MODULE Modules [0 ];
+ } MINIDUMP_MODULE_LIST,*PMINIDUMP_MODULE_LIST;
+
+ typedef struct _MINIDUMP_MEMORY_LIST {
+ ULONG32 NumberOfMemoryRanges;
+ MINIDUMP_MEMORY_DESCRIPTOR MemoryRanges [0];
+ } MINIDUMP_MEMORY_LIST,*PMINIDUMP_MEMORY_LIST;
+
+ typedef struct _MINIDUMP_MEMORY64_LIST {
+ ULONG64 NumberOfMemoryRanges;
+ RVA64 BaseRva;
+ MINIDUMP_MEMORY_DESCRIPTOR64 MemoryRanges [0];
+ } MINIDUMP_MEMORY64_LIST,*PMINIDUMP_MEMORY64_LIST;
+
+ typedef struct _MINIDUMP_EXCEPTION_INFORMATION {
+ DWORD ThreadId;
+ PEXCEPTION_POINTERS ExceptionPointers;
+ BOOL ClientPointers;
+ } MINIDUMP_EXCEPTION_INFORMATION,*PMINIDUMP_EXCEPTION_INFORMATION;
+
+ typedef struct _MINIDUMP_EXCEPTION_INFORMATION64 {
+ DWORD ThreadId;
+ ULONG64 ExceptionRecord;
+ ULONG64 ContextRecord;
+ BOOL ClientPointers;
+ } MINIDUMP_EXCEPTION_INFORMATION64,*PMINIDUMP_EXCEPTION_INFORMATION64;
+
+ typedef struct _MINIDUMP_HANDLE_DESCRIPTOR {
+ ULONG64 Handle;
+ RVA TypeNameRva;
+ RVA ObjectNameRva;
+ ULONG32 Attributes;
+ ULONG32 GrantedAccess;
+ ULONG32 HandleCount;
+ ULONG32 PointerCount;
+ } MINIDUMP_HANDLE_DESCRIPTOR,*PMINIDUMP_HANDLE_DESCRIPTOR;
+
+ typedef struct _MINIDUMP_HANDLE_DATA_STREAM {
+ ULONG32 SizeOfHeader;
+ ULONG32 SizeOfDescriptor;
+ ULONG32 NumberOfDescriptors;
+ ULONG32 Reserved;
+ } MINIDUMP_HANDLE_DATA_STREAM,*PMINIDUMP_HANDLE_DATA_STREAM;
+
+ typedef struct _MINIDUMP_FUNCTION_TABLE_DESCRIPTOR {
+ ULONG64 MinimumAddress;
+ ULONG64 MaximumAddress;
+ ULONG64 BaseAddress;
+ ULONG32 EntryCount;
+ ULONG32 SizeOfAlignPad;
+ } MINIDUMP_FUNCTION_TABLE_DESCRIPTOR,*PMINIDUMP_FUNCTION_TABLE_DESCRIPTOR;
+
+ typedef struct _MINIDUMP_FUNCTION_TABLE_STREAM {
+ ULONG32 SizeOfHeader;
+ ULONG32 SizeOfDescriptor;
+ ULONG32 SizeOfNativeDescriptor;
+ ULONG32 SizeOfFunctionEntry;
+ ULONG32 NumberOfDescriptors;
+ ULONG32 SizeOfAlignPad;
+ } MINIDUMP_FUNCTION_TABLE_STREAM,*PMINIDUMP_FUNCTION_TABLE_STREAM;
+
+ typedef struct _MINIDUMP_UNLOADED_MODULE {
+ ULONG64 BaseOfImage;
+ ULONG32 SizeOfImage;
+ ULONG32 CheckSum;
+ ULONG32 TimeDateStamp;
+ RVA ModuleNameRva;
+ } MINIDUMP_UNLOADED_MODULE,*PMINIDUMP_UNLOADED_MODULE;
+
+ typedef struct _MINIDUMP_UNLOADED_MODULE_LIST {
+ ULONG32 SizeOfHeader;
+ ULONG32 SizeOfEntry;
+ ULONG32 NumberOfEntries;
+ } MINIDUMP_UNLOADED_MODULE_LIST,*PMINIDUMP_UNLOADED_MODULE_LIST;
+
+#define MINIDUMP_MISC1_PROCESS_ID 0x00000001
+#define MINIDUMP_MISC1_PROCESS_TIMES 0x00000002
+
+ typedef struct _MINIDUMP_MISC_INFO {
+ ULONG32 SizeOfInfo;
+ ULONG32 Flags1;
+ ULONG32 ProcessId;
+ ULONG32 ProcessCreateTime;
+ ULONG32 ProcessUserTime;
+ ULONG32 ProcessKernelTime;
+ } MINIDUMP_MISC_INFO,*PMINIDUMP_MISC_INFO;
+
+ typedef struct _MINIDUMP_USER_RECORD {
+ ULONG32 Type;
+ MINIDUMP_LOCATION_DESCRIPTOR Memory;
+ } MINIDUMP_USER_RECORD,*PMINIDUMP_USER_RECORD;
+
+ typedef struct _MINIDUMP_USER_STREAM {
+ ULONG32 Type;
+ ULONG BufferSize;
+ PVOID Buffer;
+ } MINIDUMP_USER_STREAM,*PMINIDUMP_USER_STREAM;
+
+ typedef struct _MINIDUMP_USER_STREAM_INFORMATION {
+ ULONG UserStreamCount;
+ PMINIDUMP_USER_STREAM UserStreamArray;
+ } MINIDUMP_USER_STREAM_INFORMATION,*PMINIDUMP_USER_STREAM_INFORMATION;
+
+ typedef enum _MINIDUMP_CALLBACK_TYPE {
+ ModuleCallback,ThreadCallback,ThreadExCallback,IncludeThreadCallback,IncludeModuleCallback,MemoryCallback
+ } MINIDUMP_CALLBACK_TYPE;
+
+ typedef struct _MINIDUMP_THREAD_CALLBACK {
+ ULONG ThreadId;
+ HANDLE ThreadHandle;
+ CONTEXT Context;
+ ULONG SizeOfContext;
+ ULONG64 StackBase;
+ ULONG64 StackEnd;
+ } MINIDUMP_THREAD_CALLBACK,*PMINIDUMP_THREAD_CALLBACK;
+
+ typedef struct _MINIDUMP_THREAD_EX_CALLBACK {
+ ULONG ThreadId;
+ HANDLE ThreadHandle;
+ CONTEXT Context;
+ ULONG SizeOfContext;
+ ULONG64 StackBase;
+ ULONG64 StackEnd;
+ ULONG64 BackingStoreBase;
+ ULONG64 BackingStoreEnd;
+ } MINIDUMP_THREAD_EX_CALLBACK,*PMINIDUMP_THREAD_EX_CALLBACK;
+
+ typedef struct _MINIDUMP_INCLUDE_THREAD_CALLBACK {
+ ULONG ThreadId;
+ } MINIDUMP_INCLUDE_THREAD_CALLBACK,*PMINIDUMP_INCLUDE_THREAD_CALLBACK;
+
+ typedef enum _THREAD_WRITE_FLAGS {
+ ThreadWriteThread = 0x0001,ThreadWriteStack = 0x0002,ThreadWriteContext = 0x0004,ThreadWriteBackingStore = 0x0008,
+ ThreadWriteInstructionWindow = 0x0010,ThreadWriteThreadData = 0x0020
+ } THREAD_WRITE_FLAGS;
+
+ typedef struct _MINIDUMP_MODULE_CALLBACK {
+ PWCHAR FullPath;
+ ULONG64 BaseOfImage;
+ ULONG SizeOfImage;
+ ULONG CheckSum;
+ ULONG TimeDateStamp;
+ VS_FIXEDFILEINFO VersionInfo;
+ PVOID CvRecord;
+ ULONG SizeOfCvRecord;
+ PVOID MiscRecord;
+ ULONG SizeOfMiscRecord;
+ } MINIDUMP_MODULE_CALLBACK,*PMINIDUMP_MODULE_CALLBACK;
+
+ typedef struct _MINIDUMP_INCLUDE_MODULE_CALLBACK {
+ ULONG64 BaseOfImage;
+ } MINIDUMP_INCLUDE_MODULE_CALLBACK,*PMINIDUMP_INCLUDE_MODULE_CALLBACK;
+
+ typedef enum _MODULE_WRITE_FLAGS {
+ ModuleWriteModule = 0x0001,ModuleWriteDataSeg = 0x0002,ModuleWriteMiscRecord = 0x0004,ModuleWriteCvRecord = 0x0008,
+ ModuleReferencedByMemory = 0x0010
+ } MODULE_WRITE_FLAGS;
+
+ typedef struct _MINIDUMP_CALLBACK_INPUT {
+ ULONG ProcessId;
+ HANDLE ProcessHandle;
+ ULONG CallbackType;
+ union {
+ MINIDUMP_THREAD_CALLBACK Thread;
+ MINIDUMP_THREAD_EX_CALLBACK ThreadEx;
+ MINIDUMP_MODULE_CALLBACK Module;
+ MINIDUMP_INCLUDE_THREAD_CALLBACK IncludeThread;
+ MINIDUMP_INCLUDE_MODULE_CALLBACK IncludeModule;
+ } DUMMYUNIONNAME;
+ } MINIDUMP_CALLBACK_INPUT,*PMINIDUMP_CALLBACK_INPUT;
+
+ typedef struct _MINIDUMP_CALLBACK_OUTPUT {
+ union {
+ ULONG ModuleWriteFlags;
+ ULONG ThreadWriteFlags;
+ struct {
+ ULONG64 MemoryBase;
+ ULONG MemorySize;
+ } DUMMYSTRUCTNAME;
+ } DUMMYUNIONNAME;
+ } MINIDUMP_CALLBACK_OUTPUT,*PMINIDUMP_CALLBACK_OUTPUT;
+
+ typedef enum _MINIDUMP_TYPE {
+ MiniDumpNormal = 0x0000,MiniDumpWithDataSegs = 0x0001,MiniDumpWithFullMemory = 0x0002,MiniDumpWithHandleData = 0x0004,
+ MiniDumpFilterMemory = 0x0008,MiniDumpScanMemory = 0x0010,MiniDumpWithUnloadedModules = 0x0020,MiniDumpWithIndirectlyReferencedMemory = 0x0040,
+ MiniDumpFilterModulePaths = 0x0080,MiniDumpWithProcessThreadData = 0x0100,MiniDumpWithPrivateReadWriteMemory = 0x0200,
+ MiniDumpWithoutOptionalData = 0x0400
+ } MINIDUMP_TYPE;
+
+ typedef BOOL (WINAPI *MINIDUMP_CALLBACK_ROUTINE)(PVOID CallbackParam,CONST PMINIDUMP_CALLBACK_INPUT CallbackInput,PMINIDUMP_CALLBACK_OUTPUT CallbackOutput);
+
+ typedef struct _MINIDUMP_CALLBACK_INFORMATION {
+ MINIDUMP_CALLBACK_ROUTINE CallbackRoutine;
+ PVOID CallbackParam;
+ } MINIDUMP_CALLBACK_INFORMATION,*PMINIDUMP_CALLBACK_INFORMATION;
+
+#define RVA_TO_ADDR(Mapping,Rva) ((PVOID)(((ULONG_PTR) (Mapping)) + (Rva)))
+
+ BOOL WINAPI MiniDumpWriteDump(HANDLE hProcess,DWORD ProcessId,HANDLE hFile,MINIDUMP_TYPE DumpType,CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam);
+ BOOL WINAPI MiniDumpReadDumpStream(PVOID BaseOfDump,ULONG StreamNumber,PMINIDUMP_DIRECTORY *Dir,PVOID *StreamPointer,ULONG *StreamSize);
+
+#include <poppack.h>
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index c11f7d383db..76bd7ace526 100644
--- a/src/gallium/auxiliary/util/u_blit.c
+++ b/src/gallium/auxiliary/util/u_blit.c
@@ -199,6 +199,7 @@ get_next_slot( struct blit_state *ctx )
if (!ctx->vbuf) {
ctx->vbuf = pipe_buffer_create(ctx->pipe->screen,
PIPE_BIND_VERTEX_BUFFER,
+ PIPE_USAGE_STREAM,
max_slots * sizeof ctx->vertices);
}
@@ -480,6 +481,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
cso_save_vertex_shader(ctx->cso);
cso_save_clip(ctx->cso);
cso_save_vertex_elements(ctx->cso);
+ cso_save_vertex_buffers(ctx->cso);
/* set misc state we care about */
cso_set_blend(ctx->cso, &ctx->blend);
@@ -554,7 +556,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
s1, t1,
z);
- util_draw_vertex_buffer(ctx->pipe, ctx->vbuf, offset,
+ util_draw_vertex_buffer(ctx->pipe, ctx->cso, ctx->vbuf, offset,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
2); /* attribs/vert */
@@ -571,6 +573,7 @@ util_blit_pixels_writemask(struct blit_state *ctx,
cso_restore_vertex_shader(ctx->cso);
cso_restore_clip(ctx->cso);
cso_restore_vertex_elements(ctx->cso);
+ cso_restore_vertex_buffers(ctx->cso);
pipe_sampler_view_reference(&sampler_view, NULL);
}
@@ -672,6 +675,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
cso_save_vertex_shader(ctx->cso);
cso_save_clip(ctx->cso);
cso_save_vertex_elements(ctx->cso);
+ cso_save_vertex_buffers(ctx->cso);
/* set misc state we care about */
cso_set_blend(ctx->cso, &ctx->blend);
@@ -722,7 +726,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
s0, t0, s1, t1,
z);
- util_draw_vertex_buffer(ctx->pipe,
+ util_draw_vertex_buffer(ctx->pipe, ctx->cso,
ctx->vbuf, offset,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
@@ -740,4 +744,5 @@ util_blit_pixels_tex(struct blit_state *ctx,
cso_restore_vertex_shader(ctx->cso);
cso_restore_clip(ctx->cso);
cso_restore_vertex_elements(ctx->cso);
+ cso_restore_vertex_buffers(ctx->cso);
}
diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c
index 545021d2642..fd1c2b72d04 100644
--- a/src/gallium/auxiliary/util/u_blitter.c
+++ b/src/gallium/auxiliary/util/u_blitter.c
@@ -86,7 +86,6 @@ struct blitter_context_priv
void *dsa_write_depth_keep_stencil;
void *dsa_keep_depth_stencil;
void *dsa_keep_depth_write_stencil;
- void *dsa_flush_depth_stencil;
void *velem_state;
@@ -156,10 +155,6 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
ctx->dsa_keep_depth_stencil =
pipe->create_depth_stencil_alpha_state(pipe, &dsa);
- dsa.depth.writemask = 1;
- ctx->dsa_flush_depth_stencil =
- pipe->create_depth_stencil_alpha_state(pipe, &dsa);
-
dsa.depth.enabled = 1;
dsa.depth.writemask = 1;
dsa.depth.func = PIPE_FUNC_ALWAYS;
@@ -225,9 +220,10 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe)
ctx->vertices[i][0][3] = 1; /*v.w*/
/* create the vertex buffer */
- ctx->vbuf = pipe_buffer_create(ctx->base.pipe->screen,
- PIPE_BIND_VERTEX_BUFFER,
- sizeof(ctx->vertices));
+ ctx->vbuf = pipe_user_buffer_create(ctx->base.pipe->screen,
+ ctx->vertices,
+ sizeof(ctx->vertices),
+ PIPE_BIND_VERTEX_BUFFER);
return &ctx->base;
}
@@ -245,7 +241,6 @@ void util_blitter_destroy(struct blitter_context *blitter)
ctx->dsa_write_depth_keep_stencil);
pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
- pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_flush_depth_stencil);
pipe->delete_rasterizer_state(pipe, ctx->rs_state);
pipe->delete_vs_state(pipe, ctx->vs);
@@ -272,6 +267,12 @@ void util_blitter_destroy(struct blitter_context *blitter)
static void blitter_check_saved_CSOs(struct blitter_context_priv *ctx)
{
+ if (ctx->base.running) {
+ _debug_printf("u_blitter: Caught recursion on save. "
+ "This is a driver bug.\n");
+ }
+ ctx->base.running = TRUE;
+
/* make sure these CSOs have been saved */
assert(ctx->base.saved_blend_state != INVALID_PTR &&
ctx->base.saved_dsa_state != INVALID_PTR &&
@@ -302,7 +303,6 @@ static void blitter_restore_CSOs(struct blitter_context_priv *ctx)
ctx->base.saved_velem_state = INVALID_PTR;
pipe->set_stencil_ref(pipe, &ctx->base.saved_stencil_ref);
-
pipe->set_viewport_state(pipe, &ctx->base.saved_viewport);
pipe->set_clip_state(pipe, &ctx->base.saved_clip);
@@ -346,6 +346,12 @@ static void blitter_restore_CSOs(struct blitter_context_priv *ctx)
}
ctx->base.saved_num_vertex_buffers = ~0;
}
+
+ if (!ctx->base.running) {
+ _debug_printf("u_blitter: Caught recursion on restore. "
+ "This is a driver bug.\n");
+ }
+ ctx->base.running = FALSE;
}
static void blitter_set_rectangle(struct blitter_context_priv *ctx,
@@ -509,22 +515,6 @@ static void blitter_set_dst_dimensions(struct blitter_context_priv *ctx,
ctx->dst_height = height;
}
-static void blitter_draw_quad(struct blitter_context_priv *ctx)
-{
- struct pipe_context *pipe = ctx->base.pipe;
- struct pipe_box box;
-
- /* write vertices and draw them */
- u_box_1d(0, sizeof(ctx->vertices), &box);
- pipe->transfer_inline_write(pipe, ctx->vbuf, 0,
- PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
- &box, ctx->vertices, sizeof(ctx->vertices), 0);
-
- util_draw_vertex_buffer(pipe, ctx->vbuf, 0, PIPE_PRIM_TRIANGLE_FAN,
- 4, /* verts */
- 2); /* attribs/vert */
-}
-
static INLINE
void **blitter_get_sampler_state(struct blitter_context_priv *ctx,
int miplevel, boolean normalized)
@@ -649,15 +639,19 @@ static void blitter_draw_rectangle(struct blitter_context *blitter,
}
blitter_set_rectangle(ctx, x1, y1, x2, y2, depth);
- blitter_draw_quad(ctx);
+ ctx->base.pipe->redefine_user_buffer(ctx->base.pipe, ctx->vbuf,
+ 0, ctx->vbuf->width0);
+ util_draw_vertex_buffer(ctx->base.pipe, NULL, ctx->vbuf, 0,
+ PIPE_PRIM_TRIANGLE_FAN, 4, 2);
}
-void util_blitter_clear(struct blitter_context *blitter,
- unsigned width, unsigned height,
- unsigned num_cbufs,
- unsigned clear_buffers,
- const float *rgba,
- double depth, unsigned stencil)
+static void util_blitter_clear_custom(struct blitter_context *blitter,
+ unsigned width, unsigned height,
+ unsigned num_cbufs,
+ unsigned clear_buffers,
+ const float *rgba,
+ double depth, unsigned stencil,
+ void *custom_blend, void *custom_dsa)
{
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
struct pipe_context *pipe = ctx->base.pipe;
@@ -668,26 +662,28 @@ void util_blitter_clear(struct blitter_context *blitter,
blitter_check_saved_CSOs(ctx);
/* bind CSOs */
- if (clear_buffers & PIPE_CLEAR_COLOR)
+ if (custom_blend) {
+ pipe->bind_blend_state(pipe, custom_blend);
+ } else if (clear_buffers & PIPE_CLEAR_COLOR) {
pipe->bind_blend_state(pipe, ctx->blend_write_color);
- else
+ } else {
pipe->bind_blend_state(pipe, ctx->blend_keep_color);
+ }
- if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
- sr.ref_value[0] = stencil & 0xff;
+ if (custom_dsa) {
+ pipe->bind_depth_stencil_alpha_state(pipe, custom_dsa);
+ } else if ((clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) {
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil);
- pipe->set_stencil_ref(pipe, &sr);
- }
- else if (clear_buffers & PIPE_CLEAR_DEPTH) {
+ } else if (clear_buffers & PIPE_CLEAR_DEPTH) {
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil);
- }
- else if (clear_buffers & PIPE_CLEAR_STENCIL) {
- sr.ref_value[0] = stencil & 0xff;
+ } else if (clear_buffers & PIPE_CLEAR_STENCIL) {
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil);
- pipe->set_stencil_ref(pipe, &sr);
- }
- else
+ } else {
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil);
+ }
+
+ sr.ref_value[0] = stencil & 0xff;
+ pipe->set_stencil_ref(pipe, &sr);
pipe->bind_rasterizer_state(pipe, ctx->rs_state);
pipe->bind_vertex_elements_state(pipe, ctx->velem_state);
@@ -700,6 +696,27 @@ void util_blitter_clear(struct blitter_context *blitter,
blitter_restore_CSOs(ctx);
}
+void util_blitter_clear(struct blitter_context *blitter,
+ unsigned width, unsigned height,
+ unsigned num_cbufs,
+ unsigned clear_buffers,
+ const float *rgba,
+ double depth, unsigned stencil)
+{
+ util_blitter_clear_custom(blitter, width, height, num_cbufs,
+ clear_buffers, rgba, depth, stencil,
+ NULL, NULL);
+}
+
+void util_blitter_clear_depth_custom(struct blitter_context *blitter,
+ unsigned width, unsigned height,
+ double depth, void *custom_dsa)
+{
+ const float rgba[4] = {0, 0, 0, 0};
+ util_blitter_clear_custom(blitter, width, height, 0,
+ 0, rgba, depth, 0, NULL, custom_dsa);
+}
+
static
boolean is_overlap(unsigned sx1, unsigned sx2, unsigned sy1, unsigned sy2,
unsigned dx1, unsigned dx2, unsigned dy1, unsigned dy2)
@@ -737,9 +754,6 @@ void util_blitter_copy_region(struct blitter_context *blitter,
if (dst == src) {
assert(!is_overlap(srcbox->x, srcbox->x + width, srcbox->y, srcbox->y + height,
dstx, dstx + width, dsty, dsty + height));
- } else {
- assert(util_is_format_compatible(util_format_description(src->format),
- util_format_description(dst->format)));
}
assert(src->target < PIPE_MAX_TEXTURE_TYPES);
/* XXX should handle 3d regions */
@@ -761,8 +775,10 @@ void util_blitter_copy_region(struct blitter_context *blitter,
dst->nr_samples, bind, 0) ||
!screen->is_format_supported(screen, src->format, src->target,
src->nr_samples, PIPE_BIND_SAMPLER_VIEW, 0)) {
+ ctx->base.running = TRUE;
util_resource_copy_region(pipe, dst, dstlevel, dstx, dsty, dstz,
src, srclevel, srcbox);
+ ctx->base.running = FALSE;
return;
}
@@ -853,7 +869,10 @@ void util_blitter_copy_region(struct blitter_context *blitter,
/* Draw. */
blitter_set_rectangle(ctx, dstx, dsty, dstx+width, dsty+height, 0);
- blitter_draw_quad(ctx);
+ ctx->base.pipe->redefine_user_buffer(ctx->base.pipe, ctx->vbuf,
+ 0, ctx->vbuf->width0);
+ util_draw_vertex_buffer(ctx->base.pipe, NULL, ctx->vbuf, 0,
+ PIPE_PRIM_TRIANGLE_FAN, 4, 2);
break;
default:
@@ -1014,12 +1033,3 @@ void util_blitter_custom_depth_stencil(struct blitter_context *blitter,
UTIL_BLITTER_ATTRIB_NONE, NULL);
blitter_restore_CSOs(ctx);
}
-
-/* flush a region of a depth stencil surface for r300g */
-void util_blitter_flush_depth_stencil(struct blitter_context *blitter,
- struct pipe_surface *dstsurf)
-{
- struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter;
- util_blitter_custom_depth_stencil(blitter, dstsurf, NULL,
- ctx->dsa_flush_depth_stencil, 0.0f);
-}
diff --git a/src/gallium/auxiliary/util/u_blitter.h b/src/gallium/auxiliary/util/u_blitter.h
index 922a8580ac1..41470d92bba 100644
--- a/src/gallium/auxiliary/util/u_blitter.h
+++ b/src/gallium/auxiliary/util/u_blitter.h
@@ -55,13 +55,13 @@ struct blitter_context
* \param y1 A Y coordinate of the top-left corner.
* \param x2 An X coordinate of the bottom-right corner.
* \param y2 A Y coordinate of the bottom-right corner.
- * \param depth A depth which the rectangle is rendered at.
+ * \param depth A depth which the rectangle is rendered at.
*
* \param type Semantics of the attributes "attrib".
* If type is UTIL_BLITTER_ATTRIB_NONE, ignore them.
* If type is UTIL_BLITTER_ATTRIB_COLOR, the attributes
- * make up a constant RGBA color, and should go to the COLOR0
- * varying slot of a fragment shader.
+ * make up a constant RGBA color, and should go
+ * to the GENERIC0 varying slot of a fragment shader.
* If type is UTIL_BLITTER_ATTRIB_TEXCOORD, {a1, a2} and
* {a3, a4} specify top-left and bottom-right texture
* coordinates of the rectangle, respectively, and should go
@@ -79,6 +79,9 @@ struct blitter_context
enum blitter_attrib_type type,
const float attrib[4]);
+ /* Whether the blitter is running. */
+ boolean running;
+
/* Private members, really. */
struct pipe_context *pipe; /**< pipe context */
@@ -141,6 +144,10 @@ void util_blitter_clear(struct blitter_context *blitter,
const float *rgba,
double depth, unsigned stencil);
+void util_blitter_clear_depth_custom(struct blitter_context *blitter,
+ unsigned width, unsigned height,
+ double depth, void *custom_dsa);
+
/**
* Copy a block of pixels from one surface to another.
*
@@ -200,9 +207,6 @@ void util_blitter_clear_depth_stencil(struct blitter_context *blitter,
unsigned dstx, unsigned dsty,
unsigned width, unsigned height);
-void util_blitter_flush_depth_stencil(struct blitter_context *blitter,
- struct pipe_surface *dstsurf);
-
void util_blitter_custom_depth_stencil(struct blitter_context *blitter,
struct pipe_surface *zsurf,
struct pipe_surface *cbsurf,
diff --git a/src/gallium/auxiliary/util/u_debug.c b/src/gallium/auxiliary/util/u_debug.c
index f4ad545bee7..36ce4b57713 100644
--- a/src/gallium/auxiliary/util/u_debug.c
+++ b/src/gallium/auxiliary/util/u_debug.c
@@ -44,6 +44,7 @@
#include "util/u_surface.h"
#include <limits.h> /* CHAR_BIT */
+#include <ctype.h> /* isalnum */
void _debug_vprintf(const char *format, va_list ap)
{
@@ -180,6 +181,48 @@ debug_get_num_option(const char *name, long dfault)
return result;
}
+static boolean str_has_option(const char *str, const char *name)
+{
+ /* Empty string. */
+ if (!*str) {
+ return FALSE;
+ }
+
+ /* OPTION=all */
+ if (!util_strcmp(str, "all")) {
+ return TRUE;
+ }
+
+ /* Find 'name' in 'str' surrounded by non-alphanumeric characters. */
+ {
+ const char *start = str;
+ unsigned name_len = strlen(name);
+
+ /* 'start' is the beginning of the currently-parsed word,
+ * we increment 'str' each iteration.
+ * if we find either the end of string or a non-alphanumeric character,
+ * we compare 'start' up to 'str-1' with 'name'. */
+
+ while (1) {
+ if (!*str || !isalnum(*str)) {
+ if (str-start == name_len &&
+ !memcmp(start, name, name_len)) {
+ return TRUE;
+ }
+
+ if (!*str) {
+ return FALSE;
+ }
+
+ start = str+1;
+ }
+
+ str++;
+ }
+ }
+
+ return FALSE;
+}
unsigned long
debug_get_flags_option(const char *name,
@@ -207,7 +250,7 @@ debug_get_flags_option(const char *name,
else {
result = 0;
while( flags->name ) {
- if (!util_strcmp(str, "all") || util_strstr(str, flags->name ))
+ if (str_has_option(str, flags->name))
result |= flags->value;
++flags;
}
@@ -359,6 +402,41 @@ const char *u_prim_name( unsigned prim )
+#ifdef DEBUG
+int fl_indent = 0;
+const char* fl_function[1024];
+
+int debug_funclog_enter(const char* f, const int line, const char* file)
+{
+ int i;
+
+ for (i = 0; i < fl_indent; i++)
+ debug_printf(" ");
+ debug_printf("%s\n", f);
+
+ assert(fl_indent < 1023);
+ fl_function[fl_indent++] = f;
+
+ return 0;
+}
+
+void debug_funclog_exit(const char* f, const int line, const char* file)
+{
+ --fl_indent;
+ assert(fl_indent >= 0);
+ assert(fl_function[fl_indent] == f);
+}
+
+void debug_funclog_enter_exit(const char* f, const int line, const char* file)
+{
+ int i;
+ for (i = 0; i < fl_indent; i++)
+ debug_printf(" ");
+ debug_printf("%s\n", f);
+}
+#endif
+
+
#ifdef DEBUG
/**
diff --git a/src/gallium/auxiliary/util/u_debug.h b/src/gallium/auxiliary/util/u_debug.h
index 1c9624ea3ed..c47c13c64cf 100644
--- a/src/gallium/auxiliary/util/u_debug.h
+++ b/src/gallium/auxiliary/util/u_debug.h
@@ -280,6 +280,43 @@ debug_dump_flags(const struct debug_named_value *names,
/**
+ * Function enter exit loggers
+ */
+#ifdef DEBUG
+int debug_funclog_enter(const char* f, const int line, const char* file);
+void debug_funclog_exit(const char* f, const int line, const char* file);
+void debug_funclog_enter_exit(const char* f, const int line, const char* file);
+
+#define DEBUG_FUNCLOG_ENTER() \
+ int __debug_decleration_work_around = \
+ debug_funclog_enter(__FUNCTION__, __LINE__, __FILE__)
+#define DEBUG_FUNCLOG_EXIT() \
+ do { \
+ (void)__debug_decleration_work_around; \
+ debug_funclog_exit(__FUNCTION__, __LINE__, __FILE__); \
+ return; \
+ } while(0)
+#define DEBUG_FUNCLOG_EXIT_RET(ret) \
+ do { \
+ (void)__debug_decleration_work_around; \
+ debug_funclog_exit(__FUNCTION__, __LINE__, __FILE__); \
+ return ret; \
+ } while(0)
+#define DEBUG_FUNCLOG_ENTER_EXIT() \
+ debug_funclog_enter_exit(__FUNCTION__, __LINE__, __FILE__)
+
+#else
+#define DEBUG_FUNCLOG_ENTER() \
+ int __debug_decleration_work_around
+#define DEBUG_FUNCLOG_EXIT() \
+ do { (void)__debug_decleration_work_around; return; } while(0)
+#define DEBUG_FUNCLOG_EXIT_RET(ret) \
+ do { (void)__debug_decleration_work_around; return ret; } while(0)
+#define DEBUG_FUNCLOG_ENTER_EXIT()
+#endif
+
+
+/**
* Get option.
*
* It is an alias for getenv on Linux.
diff --git a/src/gallium/auxiliary/util/u_debug_refcnt.c b/src/gallium/auxiliary/util/u_debug_refcnt.c
index 40a26c9c697..6f706a35fda 100644
--- a/src/gallium/auxiliary/util/u_debug_refcnt.c
+++ b/src/gallium/auxiliary/util/u_debug_refcnt.c
@@ -43,7 +43,8 @@ int debug_refcnt_state;
struct os_stream* stream;
/* TODO: maybe move this serial machinery to a stand-alone module and expose it? */
-static pipe_mutex serials_mutex;
+pipe_static_mutex(serials_mutex);
+
static struct util_hash_table* serials_hash;
static unsigned serials_last;
@@ -66,6 +67,15 @@ static boolean debug_serial(void* p, unsigned* pserial)
{
unsigned serial;
boolean found = TRUE;
+#ifdef PIPE_SUBSYSTEM_WINDOWS_USER
+ static boolean first = TRUE;
+
+ if (first) {
+ pipe_mutex_init(serials_mutex);
+ first = FALSE;
+ }
+#endif
+
pipe_mutex_lock(serials_mutex);
if(!serials_hash)
serials_hash = util_hash_table_create(hash_ptr, compare_ptr);
diff --git a/src/gallium/auxiliary/util/u_debug_symbol.c b/src/gallium/auxiliary/util/u_debug_symbol.c
index 44d437747a1..bae9be87a26 100644
--- a/src/gallium/auxiliary/util/u_debug_symbol.c
+++ b/src/gallium/auxiliary/util/u_debug_symbol.c
@@ -40,20 +40,43 @@
#include "u_debug_symbol.h"
#include "u_hash_table.h"
-#if defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86)
+#if defined(PIPE_OS_WINDOWS) && defined(PIPE_ARCH_X86)
#include <windows.h>
#include <stddef.h>
-#include <imagehlp.h>
-/*
- * TODO: Cleanup code.
- * TODO: Support x86_64
- */
+#include "dbghelp.h"
+
static BOOL bSymInitialized = FALSE;
-static HMODULE hModule_Imagehlp = NULL;
+static HMODULE hModule_Dbghelp = NULL;
+
+
+static
+FARPROC WINAPI __GetProcAddress(LPCSTR lpProcName)
+{
+#ifdef PIPE_CC_GCC
+ if (!hModule_Dbghelp) {
+ /*
+ * bfdhelp.dll is a dbghelp.dll look-alike replacement, which is able to
+ * understand MinGW symbols using BFD library. It is available from
+ * http://people.freedesktop.org/~jrfonseca/bfdhelp/ for now.
+ */
+ hModule_Dbghelp = LoadLibraryA("bfdhelp.dll");
+ }
+#endif
+
+ if (!hModule_Dbghelp) {
+ hModule_Dbghelp = LoadLibraryA("dbghelp.dll");
+ if (!hModule_Dbghelp) {
+ return NULL;
+ }
+ }
+
+ return GetProcAddress(hModule_Dbghelp, lpProcName);
+}
+
typedef BOOL (WINAPI *PFNSYMINITIALIZE)(HANDLE, LPSTR, BOOL);
static PFNSYMINITIALIZE pfnSymInitialize = NULL;
@@ -62,8 +85,7 @@ static
BOOL WINAPI j_SymInitialize(HANDLE hProcess, PSTR UserSearchPath, BOOL fInvadeProcess)
{
if(
- (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) &&
- (pfnSymInitialize || (pfnSymInitialize = (PFNSYMINITIALIZE) GetProcAddress(hModule_Imagehlp, "SymInitialize")))
+ (pfnSymInitialize || (pfnSymInitialize = (PFNSYMINITIALIZE) __GetProcAddress("SymInitialize")))
)
return pfnSymInitialize(hProcess, UserSearchPath, fInvadeProcess);
else
@@ -77,57 +99,41 @@ static
DWORD WINAPI j_SymSetOptions(DWORD SymOptions)
{
if(
- (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) &&
- (pfnSymSetOptions || (pfnSymSetOptions = (PFNSYMSETOPTIONS) GetProcAddress(hModule_Imagehlp, "SymSetOptions")))
+ (pfnSymSetOptions || (pfnSymSetOptions = (PFNSYMSETOPTIONS) __GetProcAddress("SymSetOptions")))
)
return pfnSymSetOptions(SymOptions);
else
return FALSE;
}
-typedef PGET_MODULE_BASE_ROUTINE PFNSYMGETMODULEBASE;
-static PFNSYMGETMODULEBASE pfnSymGetModuleBase = NULL;
+typedef BOOL (WINAPI *PFNSYMGETSYMFROMADDR)(HANDLE, DWORD64, PDWORD64, PSYMBOL_INFO);
+static PFNSYMGETSYMFROMADDR pfnSymFromAddr = NULL;
static
-DWORD WINAPI j_SymGetModuleBase(HANDLE hProcess, DWORD dwAddr)
+BOOL WINAPI j_SymFromAddr(HANDLE hProcess, DWORD64 Address, PDWORD64 Displacement, PSYMBOL_INFO Symbol)
{
if(
- (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) &&
- (pfnSymGetModuleBase || (pfnSymGetModuleBase = (PFNSYMGETMODULEBASE) GetProcAddress(hModule_Imagehlp, "SymGetModuleBase")))
+ (pfnSymFromAddr || (pfnSymFromAddr = (PFNSYMGETSYMFROMADDR) __GetProcAddress("SymFromAddr")))
)
- return pfnSymGetModuleBase(hProcess, dwAddr);
- else
- return 0;
-}
-
-typedef BOOL (WINAPI *PFNSYMGETSYMFROMADDR)(HANDLE, DWORD, LPDWORD, PIMAGEHLP_SYMBOL);
-static PFNSYMGETSYMFROMADDR pfnSymGetSymFromAddr = NULL;
-
-static
-BOOL WINAPI j_SymGetSymFromAddr(HANDLE hProcess, DWORD Address, PDWORD Displacement, PIMAGEHLP_SYMBOL Symbol)
-{
- if(
- (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) &&
- (pfnSymGetSymFromAddr || (pfnSymGetSymFromAddr = (PFNSYMGETSYMFROMADDR) GetProcAddress(hModule_Imagehlp, "SymGetSymFromAddr")))
- )
- return pfnSymGetSymFromAddr(hProcess, Address, Displacement, Symbol);
+ return pfnSymFromAddr(hProcess, Address, Displacement, Symbol);
else
return FALSE;
}
static INLINE void
-debug_symbol_name_imagehlp(const void *addr, char* buf, unsigned size)
+debug_symbol_name_dbghelp(const void *addr, char* buf, unsigned size)
{
HANDLE hProcess;
BYTE symbolBuffer[1024];
- PIMAGEHLP_SYMBOL pSymbol = (PIMAGEHLP_SYMBOL) symbolBuffer;
- DWORD dwDisplacement = 0; /* Displacement of the input address, relative to the start of the symbol */
+ PSYMBOL_INFO pSymbol = (PSYMBOL_INFO) symbolBuffer;
+ DWORD64 dwDisplacement = 0; /* Displacement of the input address, relative to the start of the symbol */
hProcess = GetCurrentProcess();
+ memset(pSymbol, 0, sizeof *pSymbol);
pSymbol->SizeOfStruct = sizeof(symbolBuffer);
- pSymbol->MaxNameLength = sizeof(symbolBuffer) - offsetof(IMAGEHLP_SYMBOL, Name);
+ pSymbol->MaxNameLen = sizeof(symbolBuffer) - offsetof(SYMBOL_INFO, Name);
if(!bSymInitialized) {
j_SymSetOptions(/* SYMOPT_UNDNAME | */ SYMOPT_LOAD_LINES);
@@ -135,7 +141,7 @@ debug_symbol_name_imagehlp(const void *addr, char* buf, unsigned size)
bSymInitialized = TRUE;
}
- if(!j_SymGetSymFromAddr(hProcess, (DWORD)addr, &dwDisplacement, pSymbol))
+ if(!j_SymFromAddr(hProcess, (DWORD64)(uintptr_t)addr, &dwDisplacement, pSymbol))
buf[0] = 0;
else
{
@@ -165,8 +171,8 @@ debug_symbol_name_glibc(const void *addr, char* buf, unsigned size)
void
debug_symbol_name(const void *addr, char* buf, unsigned size)
{
-#if defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86)
- debug_symbol_name_imagehlp(addr, buf, size);
+#if defined(PIPE_OS_WINDOWS) && defined(PIPE_ARCH_X86)
+ debug_symbol_name_dbghelp(addr, buf, size);
if(buf[0])
return;
#endif
@@ -190,7 +196,7 @@ debug_symbol_print(const void *addr)
}
struct util_hash_table* symbols_hash;
-pipe_mutex symbols_mutex;
+pipe_static_mutex(symbols_mutex);
static unsigned hash_ptr(void* p)
{
@@ -211,6 +217,15 @@ const char*
debug_symbol_name_cached(const void *addr)
{
const char* name;
+#ifdef PIPE_SUBSYSTEM_WINDOWS_USER
+ static boolean first = TRUE;
+
+ if (first) {
+ pipe_mutex_init(symbols_mutex);
+ first = FALSE;
+ }
+#endif
+
pipe_mutex_lock(symbols_mutex);
if(!symbols_hash)
symbols_hash = util_hash_table_create(hash_ptr, compare_ptr);
diff --git a/src/gallium/auxiliary/util/u_draw_quad.c b/src/gallium/auxiliary/util/u_draw_quad.c
index 0b6dc5880f3..0defd919974 100644
--- a/src/gallium/auxiliary/util/u_draw_quad.c
+++ b/src/gallium/auxiliary/util/u_draw_quad.c
@@ -31,6 +31,7 @@
#include "util/u_inlines.h"
#include "util/u_draw_quad.h"
#include "util/u_memory.h"
+#include "cso_cache/cso_context.h"
/**
@@ -39,6 +40,7 @@
*/
void
util_draw_vertex_buffer(struct pipe_context *pipe,
+ struct cso_context *cso,
struct pipe_resource *vbuf,
uint offset,
uint prim_type,
@@ -54,8 +56,12 @@ util_draw_vertex_buffer(struct pipe_context *pipe,
vbuffer.buffer = vbuf;
vbuffer.stride = num_attribs * 4 * sizeof(float); /* vertex size */
vbuffer.buffer_offset = offset;
- vbuffer.max_index = num_verts - 1;
- pipe->set_vertex_buffers(pipe, 1, &vbuffer);
+
+ if (cso) {
+ cso_set_vertex_buffers(cso, 1, &vbuffer);
+ } else {
+ pipe->set_vertex_buffers(pipe, 1, &vbuffer);
+ }
/* note: vertex elements already set by caller */
@@ -70,7 +76,7 @@ util_draw_vertex_buffer(struct pipe_context *pipe,
* Note: this isn't especially efficient.
*/
void
-util_draw_texquad(struct pipe_context *pipe,
+util_draw_texquad(struct pipe_context *pipe, struct cso_context *cso,
float x0, float y0, float x1, float y1, float z)
{
uint numAttribs = 2, i, j;
@@ -118,7 +124,7 @@ util_draw_texquad(struct pipe_context *pipe,
if (!vbuf)
goto out;
- util_draw_vertex_buffer(pipe, vbuf, 0, PIPE_PRIM_TRIANGLE_FAN, 4, 2);
+ util_draw_vertex_buffer(pipe, cso, vbuf, 0, PIPE_PRIM_TRIANGLE_FAN, 4, 2);
out:
if (vbuf)
diff --git a/src/gallium/auxiliary/util/u_draw_quad.h b/src/gallium/auxiliary/util/u_draw_quad.h
index 52994fe05c3..f1167786f0e 100644
--- a/src/gallium/auxiliary/util/u_draw_quad.h
+++ b/src/gallium/auxiliary/util/u_draw_quad.h
@@ -38,17 +38,18 @@ extern "C" {
#endif
struct pipe_resource;
+struct cso_context;
#include "util/u_draw.h"
extern void
-util_draw_vertex_buffer(struct pipe_context *pipe,
+util_draw_vertex_buffer(struct pipe_context *pipe, struct cso_context *cso,
struct pipe_resource *vbuf, uint offset,
uint num_attribs, uint num_verts, uint prim_type);
extern void
-util_draw_texquad(struct pipe_context *pipe,
+util_draw_texquad(struct pipe_context *pipe, struct cso_context *cso,
float x0, float y0, float x1, float y1, float z);
diff --git a/src/gallium/auxiliary/util/u_dump_state.c b/src/gallium/auxiliary/util/u_dump_state.c
index b471d59eebf..5ecf8cbb067 100644
--- a/src/gallium/auxiliary/util/u_dump_state.c
+++ b/src/gallium/auxiliary/util/u_dump_state.c
@@ -681,7 +681,6 @@ util_dump_vertex_buffer(struct os_stream *stream, const struct pipe_vertex_buffe
util_dump_struct_begin(stream, "pipe_vertex_buffer");
util_dump_member(stream, uint, state, stride);
- util_dump_member(stream, uint, state, max_index);
util_dump_member(stream, uint, state, buffer_offset);
util_dump_member(stream, ptr, state, buffer);
diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h
index 03b73c0e98f..7659a802a41 100644
--- a/src/gallium/auxiliary/util/u_format.h
+++ b/src/gallium/auxiliary/util/u_format.h
@@ -673,7 +673,8 @@ util_format_has_alpha(enum pipe_format format)
}
/**
- * Return the matching SRGB format, or PIPE_FORMAT_NONE if none.
+ * Given a linear RGB colorspace format, return the corresponding SRGB
+ * format, or PIPE_FORMAT_NONE if none.
*/
static INLINE enum pipe_format
util_format_srgb(enum pipe_format format)
@@ -711,6 +712,45 @@ util_format_srgb(enum pipe_format format)
}
/**
+ * Given an sRGB format, return the corresponding linear colorspace format.
+ * For non sRGB formats, return the format unchanged.
+ */
+static INLINE enum pipe_format
+util_format_linear(enum pipe_format format)
+{
+ switch (format) {
+ case PIPE_FORMAT_L8_SRGB:
+ return PIPE_FORMAT_L8_UNORM;
+ case PIPE_FORMAT_L8A8_SRGB:
+ return PIPE_FORMAT_L8A8_UNORM;
+ case PIPE_FORMAT_R8G8B8_SRGB:
+ return PIPE_FORMAT_R8G8B8_UNORM;
+ case PIPE_FORMAT_A8B8G8R8_SRGB:
+ return PIPE_FORMAT_A8B8G8R8_UNORM;
+ case PIPE_FORMAT_X8B8G8R8_SRGB:
+ return PIPE_FORMAT_X8B8G8R8_UNORM;
+ case PIPE_FORMAT_B8G8R8A8_SRGB:
+ return PIPE_FORMAT_B8G8R8A8_UNORM;
+ case PIPE_FORMAT_B8G8R8X8_SRGB:
+ return PIPE_FORMAT_B8G8R8X8_UNORM;
+ case PIPE_FORMAT_A8R8G8B8_SRGB:
+ return PIPE_FORMAT_A8R8G8B8_UNORM;
+ case PIPE_FORMAT_X8R8G8B8_SRGB:
+ return PIPE_FORMAT_X8R8G8B8_UNORM;
+ case PIPE_FORMAT_DXT1_SRGB:
+ return PIPE_FORMAT_DXT1_RGB;
+ case PIPE_FORMAT_DXT1_SRGBA:
+ return PIPE_FORMAT_DXT1_RGBA;
+ case PIPE_FORMAT_DXT3_SRGBA:
+ return PIPE_FORMAT_DXT3_RGBA;
+ case PIPE_FORMAT_DXT5_SRGBA:
+ return PIPE_FORMAT_DXT5_RGBA;
+ default:
+ return format;
+ }
+}
+
+/**
* Return the number of components stored.
* Formats with block size != 1x1 will always have 1 component (the block).
*/
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index d22ae8b375b..3b6342ad8d1 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -1350,6 +1350,7 @@ get_next_slot(struct gen_mipmap_state *ctx)
if (!ctx->vbuf) {
ctx->vbuf = pipe_buffer_create(ctx->pipe->screen,
PIPE_BIND_VERTEX_BUFFER,
+ PIPE_USAGE_STREAM,
max_slots * sizeof ctx->vertices);
}
@@ -1616,7 +1617,8 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
face,
rcoord);
- util_draw_vertex_buffer(ctx->pipe,
+ util_draw_vertex_buffer(ctx->pipe,
+ ctx->cso,
ctx->vbuf,
offset,
PIPE_PRIM_TRIANGLE_FAN,
diff --git a/src/gallium/auxiliary/util/u_index_modify.c b/src/gallium/auxiliary/util/u_index_modify.c
index f2c9db3caf1..d0a28b5fdfa 100644
--- a/src/gallium/auxiliary/util/u_index_modify.c
+++ b/src/gallium/auxiliary/util/u_index_modify.c
@@ -38,7 +38,10 @@ void util_shorten_ubyte_elts_to_userptr(struct pipe_context *context,
unsigned short *out_map = out;
unsigned i;
- in_map = pipe_buffer_map(context, elts, PIPE_TRANSFER_READ, &src_transfer);
+ in_map = pipe_buffer_map(context, elts,
+ PIPE_TRANSFER_READ |
+ PIPE_TRANSFER_UNSYNCHRONIZED,
+ &src_transfer);
in_map += start;
for (i = 0; i < count; i++) {
@@ -62,6 +65,7 @@ void util_shorten_ubyte_elts(struct pipe_context *context,
new_elts = pipe_buffer_create(context->screen,
PIPE_BIND_INDEX_BUFFER,
+ PIPE_USAGE_STATIC,
2 * count);
out_map = pipe_buffer_map(context, new_elts, PIPE_TRANSFER_WRITE,
@@ -87,7 +91,10 @@ void util_rebuild_ushort_elts_to_userptr(struct pipe_context *context,
unsigned short *out_map = out;
unsigned i;
- in_map = pipe_buffer_map(context, elts, PIPE_TRANSFER_READ, &in_transfer);
+ in_map = pipe_buffer_map(context, elts,
+ PIPE_TRANSFER_READ |
+ PIPE_TRANSFER_UNSYNCHRONIZED,
+ &in_transfer);
in_map += start;
for (i = 0; i < count; i++) {
@@ -110,6 +117,7 @@ void util_rebuild_ushort_elts(struct pipe_context *context,
new_elts = pipe_buffer_create(context->screen,
PIPE_BIND_INDEX_BUFFER,
+ PIPE_USAGE_STATIC,
2 * count);
out_map = pipe_buffer_map(context, new_elts,
@@ -135,7 +143,10 @@ void util_rebuild_uint_elts_to_userptr(struct pipe_context *context,
unsigned int *out_map = out;
unsigned i;
- in_map = pipe_buffer_map(context, elts, PIPE_TRANSFER_READ, &in_transfer);
+ in_map = pipe_buffer_map(context, elts,
+ PIPE_TRANSFER_READ |
+ PIPE_TRANSFER_UNSYNCHRONIZED,
+ &in_transfer);
in_map += start;
for (i = 0; i < count; i++) {
@@ -158,6 +169,7 @@ void util_rebuild_uint_elts(struct pipe_context *context,
new_elts = pipe_buffer_create(context->screen,
PIPE_BIND_INDEX_BUFFER,
+ PIPE_USAGE_STATIC,
2 * count);
out_map = pipe_buffer_map(context, new_elts,
diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h
index b4870bce981..98889fb70ac 100644
--- a/src/gallium/auxiliary/util/u_inlines.h
+++ b/src/gallium/auxiliary/util/u_inlines.h
@@ -160,6 +160,21 @@ pipe_surface_init(struct pipe_context *ctx, struct pipe_surface* ps,
pipe_surface_reset(ctx, ps, pt, level, layer, flags);
}
+/* Return true if the surfaces are equal. */
+static INLINE boolean
+pipe_surface_equal(struct pipe_surface *s1, struct pipe_surface *s2)
+{
+ return s1->texture == s2->texture &&
+ s1->format == s2->format &&
+ (s1->texture->target != PIPE_BUFFER ||
+ (s1->u.buf.first_element == s2->u.buf.first_element &&
+ s1->u.buf.last_element == s2->u.buf.last_element)) &&
+ (s1->texture->target == PIPE_BUFFER ||
+ (s1->u.tex.level == s2->u.tex.level &&
+ s1->u.tex.first_layer == s2->u.tex.first_layer &&
+ s1->u.tex.last_layer == s2->u.tex.last_layer));
+}
+
/*
* Convenience wrappers for screen buffer functions.
*/
@@ -167,6 +182,7 @@ pipe_surface_init(struct pipe_context *ctx, struct pipe_surface* ps,
static INLINE struct pipe_resource *
pipe_buffer_create( struct pipe_screen *screen,
unsigned bind,
+ unsigned usage,
unsigned size )
{
struct pipe_resource buffer;
@@ -174,7 +190,7 @@ pipe_buffer_create( struct pipe_screen *screen,
buffer.target = PIPE_BUFFER;
buffer.format = PIPE_FORMAT_R8_UNORM; /* want TYPELESS or similar */
buffer.bind = bind;
- buffer.usage = PIPE_USAGE_DEFAULT;
+ buffer.usage = usage;
buffer.flags = 0;
buffer.width0 = size;
buffer.height0 = 1;
@@ -220,6 +236,7 @@ pipe_buffer_map_range(struct pipe_context *pipe,
map = pipe->transfer_map( pipe, *transfer );
if (map == NULL) {
pipe->transfer_destroy( pipe, *transfer );
+ *transfer = NULL;
return NULL;
}
diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h
index 37294b7203f..30555f92a6d 100644
--- a/src/gallium/auxiliary/util/u_math.h
+++ b/src/gallium/auxiliary/util/u_math.h
@@ -176,7 +176,7 @@ static INLINE float logf( float f )
#define isfinite(x) _finite((double)(x))
#define isnan(x) _isnan((double)(x))
-#endif
+#endif /* _MSC_VER < 1400 && !defined(__cplusplus) */
static INLINE double log2( double x )
{
@@ -184,6 +184,18 @@ static INLINE double log2( double x )
return log( x ) * invln2;
}
+static INLINE double
+round(double x)
+{
+ return x >= 0.0 ? floor(x + 0.5) : ceil(x - 0.5);
+}
+
+static INLINE float
+roundf(float x)
+{
+ return x >= 0.0f ? floorf(x + 0.5f) : ceilf(x - 0.5f);
+}
+
#endif /* _MSC_VER */
diff --git a/src/gallium/auxiliary/util/u_resource.c b/src/gallium/auxiliary/util/u_resource.c
index 443c9f8067e..ea6896b430f 100644
--- a/src/gallium/auxiliary/util/u_resource.c
+++ b/src/gallium/auxiliary/util/u_resource.c
@@ -35,7 +35,7 @@ unsigned u_is_resource_referenced_vtbl( struct pipe_context *pipe,
struct pipe_transfer *u_get_transfer_vtbl(struct pipe_context *context,
struct pipe_resource *resource,
unsigned level,
- enum pipe_transfer_usage usage,
+ unsigned usage,
const struct pipe_box *box)
{
struct u_resource *ur = u_resource(resource);
diff --git a/src/gallium/auxiliary/util/u_tile.c b/src/gallium/auxiliary/util/u_tile.c
index 44cadbfcdd0..e3c7085ba92 100644
--- a/src/gallium/auxiliary/util/u_tile.c
+++ b/src/gallium/auxiliary/util/u_tile.c
@@ -367,47 +367,19 @@ pipe_get_tile_rgba(struct pipe_context *pipe,
uint x, uint y, uint w, uint h,
float *p)
{
- unsigned dst_stride = w * 4;
- void *packed;
- enum pipe_format format = pt->resource->format;
-
- if (u_clip_tile(x, y, &w, &h, &pt->box))
- return;
-
- packed = MALLOC(util_format_get_nblocks(format, w, h) * util_format_get_blocksize(format));
-
- if (!packed)
- return;
-
- if(format == PIPE_FORMAT_UYVY || format == PIPE_FORMAT_YUYV)
- assert((x & 1) == 0);
-
- pipe_get_tile_raw(pipe, pt, x, y, w, h, packed, 0);
-
- pipe_tile_raw_to_rgba(format, packed, w, h, p, dst_stride);
-
- FREE(packed);
+ pipe_get_tile_rgba_format(pipe, pt, x, y, w, h, pt->resource->format, p);
}
void
-pipe_get_tile_swizzle(struct pipe_context *pipe,
- struct pipe_transfer *pt,
- uint x,
- uint y,
- uint w,
- uint h,
- uint swizzle_r,
- uint swizzle_g,
- uint swizzle_b,
- uint swizzle_a,
- enum pipe_format format,
- float *p)
+pipe_get_tile_rgba_format(struct pipe_context *pipe,
+ struct pipe_transfer *pt,
+ uint x, uint y, uint w, uint h,
+ enum pipe_format format,
+ float *p)
{
unsigned dst_stride = w * 4;
void *packed;
- uint iy;
- float rgba01[6];
if (u_clip_tile(x, y, &w, &h, &pt->box)) {
return;
@@ -427,35 +399,6 @@ pipe_get_tile_swizzle(struct pipe_context *pipe,
pipe_tile_raw_to_rgba(format, packed, w, h, p, dst_stride);
FREE(packed);
-
- if (swizzle_r == PIPE_SWIZZLE_RED &&
- swizzle_g == PIPE_SWIZZLE_GREEN &&
- swizzle_b == PIPE_SWIZZLE_BLUE &&
- swizzle_a == PIPE_SWIZZLE_ALPHA) {
- /* no-op, skip */
- return;
- }
-
- rgba01[PIPE_SWIZZLE_ZERO] = 0.0f;
- rgba01[PIPE_SWIZZLE_ONE] = 1.0f;
-
- for (iy = 0; iy < h; iy++) {
- float *row = p;
- uint ix;
-
- for (ix = 0; ix < w; ix++) {
- rgba01[PIPE_SWIZZLE_RED] = row[0];
- rgba01[PIPE_SWIZZLE_GREEN] = row[1];
- rgba01[PIPE_SWIZZLE_BLUE] = row[2];
- rgba01[PIPE_SWIZZLE_ALPHA] = row[3];
-
- *row++ = rgba01[swizzle_r];
- *row++ = rgba01[swizzle_g];
- *row++ = rgba01[swizzle_b];
- *row++ = rgba01[swizzle_a];
- }
- p += dst_stride;
- }
}
@@ -465,9 +408,19 @@ pipe_put_tile_rgba(struct pipe_context *pipe,
uint x, uint y, uint w, uint h,
const float *p)
{
+ pipe_put_tile_rgba_format(pipe, pt, x, y, w, h, pt->resource->format, p);
+}
+
+
+void
+pipe_put_tile_rgba_format(struct pipe_context *pipe,
+ struct pipe_transfer *pt,
+ uint x, uint y, uint w, uint h,
+ enum pipe_format format,
+ const float *p)
+{
unsigned src_stride = w * 4;
void *packed;
- enum pipe_format format = pt->resource->format;
if (u_clip_tile(x, y, &w, &h, &pt->box))
return;
diff --git a/src/gallium/auxiliary/util/u_tile.h b/src/gallium/auxiliary/util/u_tile.h
index 558351d0ce5..0ba274308fe 100644
--- a/src/gallium/auxiliary/util/u_tile.h
+++ b/src/gallium/auxiliary/util/u_tile.h
@@ -80,18 +80,11 @@ pipe_get_tile_rgba(struct pipe_context *pipe,
float *p);
void
-pipe_get_tile_swizzle(struct pipe_context *pipe,
- struct pipe_transfer *pt,
- uint x,
- uint y,
- uint w,
- uint h,
- uint swizzle_r,
- uint swizzle_g,
- uint swizzle_b,
- uint swizzle_a,
- enum pipe_format format,
- float *p);
+pipe_get_tile_rgba_format(struct pipe_context *pipe,
+ struct pipe_transfer *pt,
+ uint x, uint y, uint w, uint h,
+ enum pipe_format format,
+ float *p);
void
pipe_put_tile_rgba(struct pipe_context *pipe,
@@ -99,6 +92,13 @@ pipe_put_tile_rgba(struct pipe_context *pipe,
uint x, uint y, uint w, uint h,
const float *p);
+void
+pipe_put_tile_rgba_format(struct pipe_context *pipe,
+ struct pipe_transfer *pt,
+ uint x, uint y, uint w, uint h,
+ enum pipe_format format,
+ const float *p);
+
void
pipe_get_tile_z(struct pipe_context *pipe,
diff --git a/src/gallium/auxiliary/util/u_transfer.c b/src/gallium/auxiliary/util/u_transfer.c
index e2828cfd99e..b6c63d9642f 100644
--- a/src/gallium/auxiliary/util/u_transfer.c
+++ b/src/gallium/auxiliary/util/u_transfer.c
@@ -112,3 +112,10 @@ void u_default_transfer_destroy(struct pipe_context *pipe,
FREE(transfer);
}
+void u_default_redefine_user_buffer(struct pipe_context *ctx,
+ struct pipe_resource *resource,
+ unsigned offset,
+ unsigned size)
+{
+ resource->width0 = MAX2(resource->width0, offset + size);
+}
diff --git a/src/gallium/auxiliary/util/u_transfer.h b/src/gallium/auxiliary/util/u_transfer.h
index 3412e13c3cc..8cf9c418b04 100644
--- a/src/gallium/auxiliary/util/u_transfer.h
+++ b/src/gallium/auxiliary/util/u_transfer.h
@@ -93,7 +93,7 @@ struct u_resource_vtbl {
struct u_resource {
struct pipe_resource b;
- struct u_resource_vtbl *vtbl;
+ const struct u_resource_vtbl *vtbl;
};
@@ -136,11 +136,9 @@ void u_transfer_inline_write_vtbl( struct pipe_context *rm_ctx,
unsigned stride,
unsigned layer_stride);
-
-
-
-
-
-
+void u_default_redefine_user_buffer(struct pipe_context *ctx,
+ struct pipe_resource *resource,
+ unsigned offset,
+ unsigned size);
#endif
diff --git a/src/gallium/auxiliary/util/u_upload_mgr.c b/src/gallium/auxiliary/util/u_upload_mgr.c
index 3b3d5b418fe..dcf800a1e8e 100644
--- a/src/gallium/auxiliary/util/u_upload_mgr.c
+++ b/src/gallium/auxiliary/util/u_upload_mgr.c
@@ -85,7 +85,12 @@ void u_upload_flush( struct u_upload_mgr *upload )
{
/* Unmap and unreference the upload buffer. */
if (upload->transfer) {
+ if (upload->size) {
+ pipe_buffer_flush_mapped_range(upload->pipe, upload->transfer,
+ 0, upload->size);
+ }
pipe_transfer_unmap(upload->pipe, upload->transfer);
+ pipe_transfer_destroy(upload->pipe, upload->transfer);
upload->transfer = NULL;
}
pipe_resource_reference( &upload->buffer, NULL );
@@ -116,13 +121,17 @@ u_upload_alloc_buffer( struct u_upload_mgr *upload,
upload->buffer = pipe_buffer_create( upload->pipe->screen,
upload->bind,
+ PIPE_USAGE_STREAM,
size );
if (upload->buffer == NULL)
goto fail;
/* Map the new buffer. */
- upload->map = pipe_buffer_map(upload->pipe, upload->buffer,
- PIPE_TRANSFER_WRITE, &upload->transfer);
+ upload->map = pipe_buffer_map_range(upload->pipe, upload->buffer,
+ 0, size,
+ PIPE_TRANSFER_WRITE |
+ PIPE_TRANSFER_FLUSH_EXPLICIT,
+ &upload->transfer);
upload->size = size;
diff --git a/src/gallium/auxiliary/util/u_vbuf_mgr.c b/src/gallium/auxiliary/util/u_vbuf_mgr.c
new file mode 100644
index 00000000000..dec8dd717e8
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_vbuf_mgr.c
@@ -0,0 +1,601 @@
+/**************************************************************************
+ *
+ * Copyright 2011 Marek Olšák <[email protected]>
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include "util/u_vbuf_mgr.h"
+
+#include "util/u_format.h"
+#include "util/u_inlines.h"
+#include "util/u_memory.h"
+#include "util/u_upload_mgr.h"
+#include "translate/translate.h"
+#include "translate/translate_cache.h"
+
+/* Hardware vertex fetcher limitations can be described by this structure. */
+struct u_vbuf_caps {
+ /* Vertex format CAPs. */
+ /* TRUE if hardware supports it. */
+ unsigned format_fixed32:1; /* PIPE_FORMAT_*32*_FIXED */
+ unsigned format_float16:1; /* PIPE_FORMAT_*16*_FLOAT */
+ unsigned format_float64:1; /* PIPE_FORMAT_*64*_FLOAT */
+ unsigned format_norm32:1; /* PIPE_FORMAT_*32*NORM */
+ unsigned format_scaled32:1; /* PIPE_FORMAT_*32*SCALED */
+
+ /* Whether vertex fetches don't have to be dword-aligned. */
+ /* TRUE if hardware supports it. */
+ unsigned fetch_dword_unaligned:1;
+};
+
+struct u_vbuf_mgr_elements {
+ unsigned count;
+ struct pipe_vertex_element ve[PIPE_MAX_ATTRIBS];
+
+ /* If (velem[i].src_format != real_format[i]), the vertex buffer
+ * referenced by the vertex element cannot be used for rendering and
+ * its vertex data must be translated to real_format[i]. */
+ enum pipe_format native_format[PIPE_MAX_ATTRIBS];
+ unsigned native_format_size[PIPE_MAX_ATTRIBS];
+
+ /* This might mean two things:
+ * - src_format != native_format, as discussed above.
+ * - src_offset % 4 != 0 (if the caps don't allow such an offset). */
+ boolean incompatible_layout;
+};
+
+struct u_vbuf_mgr_priv {
+ struct u_vbuf_mgr b;
+ struct u_vbuf_caps caps;
+ struct pipe_context *pipe;
+
+ struct translate_cache *translate_cache;
+ unsigned translate_vb_slot;
+
+ struct u_vbuf_mgr_elements *ve;
+ void *saved_ve, *fallback_ve;
+ boolean ve_binding_lock;
+
+ boolean any_user_vbs;
+ boolean incompatible_vb_layout;
+};
+
+static void u_vbuf_mgr_init_format_caps(struct u_vbuf_mgr_priv *mgr)
+{
+ struct pipe_screen *screen = mgr->pipe->screen;
+
+ mgr->caps.format_fixed32 =
+ screen->is_format_supported(screen, PIPE_FORMAT_R32_FIXED, PIPE_BUFFER,
+ 0, PIPE_BIND_VERTEX_BUFFER, 0);
+
+ mgr->caps.format_float16 =
+ screen->is_format_supported(screen, PIPE_FORMAT_R16_FLOAT, PIPE_BUFFER,
+ 0, PIPE_BIND_VERTEX_BUFFER, 0);
+
+ mgr->caps.format_float64 =
+ screen->is_format_supported(screen, PIPE_FORMAT_R64_FLOAT, PIPE_BUFFER,
+ 0, PIPE_BIND_VERTEX_BUFFER, 0);
+
+ mgr->caps.format_norm32 =
+ screen->is_format_supported(screen, PIPE_FORMAT_R32_UNORM, PIPE_BUFFER,
+ 0, PIPE_BIND_VERTEX_BUFFER, 0) &&
+ screen->is_format_supported(screen, PIPE_FORMAT_R32_SNORM, PIPE_BUFFER,
+ 0, PIPE_BIND_VERTEX_BUFFER, 0);
+
+ mgr->caps.format_scaled32 =
+ screen->is_format_supported(screen, PIPE_FORMAT_R32_USCALED, PIPE_BUFFER,
+ 0, PIPE_BIND_VERTEX_BUFFER, 0) &&
+ screen->is_format_supported(screen, PIPE_FORMAT_R32_SSCALED, PIPE_BUFFER,
+ 0, PIPE_BIND_VERTEX_BUFFER, 0);
+}
+
+struct u_vbuf_mgr *
+u_vbuf_mgr_create(struct pipe_context *pipe,
+ unsigned upload_buffer_size,
+ unsigned upload_buffer_alignment,
+ unsigned upload_buffer_bind,
+ enum u_fetch_alignment fetch_alignment)
+{
+ struct u_vbuf_mgr_priv *mgr = CALLOC_STRUCT(u_vbuf_mgr_priv);
+
+ mgr->pipe = pipe;
+ mgr->translate_cache = translate_cache_create();
+
+ mgr->b.uploader = u_upload_create(pipe, upload_buffer_size,
+ upload_buffer_alignment,
+ upload_buffer_bind);
+
+ mgr->caps.fetch_dword_unaligned =
+ fetch_alignment == U_VERTEX_FETCH_BYTE_ALIGNED;
+
+ u_vbuf_mgr_init_format_caps(mgr);
+
+ return &mgr->b;
+}
+
+void u_vbuf_mgr_destroy(struct u_vbuf_mgr *mgrb)
+{
+ struct u_vbuf_mgr_priv *mgr = (struct u_vbuf_mgr_priv*)mgrb;
+ unsigned i;
+
+ for (i = 0; i < mgr->b.nr_real_vertex_buffers; i++) {
+ pipe_resource_reference(&mgr->b.vertex_buffer[i].buffer, NULL);
+ pipe_resource_reference(&mgr->b.real_vertex_buffer[i], NULL);
+ }
+
+ translate_cache_destroy(mgr->translate_cache);
+ u_upload_destroy(mgr->b.uploader);
+ FREE(mgr);
+}
+
+
+static void u_vbuf_translate_begin(struct u_vbuf_mgr_priv *mgr,
+ int min_index, int max_index,
+ boolean *upload_flushed)
+{
+ struct translate_key key;
+ struct translate_element *te;
+ unsigned tr_elem_index[PIPE_MAX_ATTRIBS];
+ struct translate *tr;
+ boolean vb_translated[PIPE_MAX_ATTRIBS] = {0};
+ uint8_t *vb_map[PIPE_MAX_ATTRIBS] = {0}, *out_map;
+ struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {0};
+ struct pipe_resource *out_buffer = NULL;
+ unsigned i, num_verts, out_offset;
+ struct pipe_vertex_element new_velems[PIPE_MAX_ATTRIBS];
+
+ memset(&key, 0, sizeof(key));
+ memset(tr_elem_index, 0xff, sizeof(tr_elem_index));
+
+ /* Initialize the translate key, i.e. the recipe how vertices should be
+ * translated. */
+ for (i = 0; i < mgr->ve->count; i++) {
+ struct pipe_vertex_buffer *vb =
+ &mgr->b.vertex_buffer[mgr->ve->ve[i].vertex_buffer_index];
+ enum pipe_format output_format = mgr->ve->native_format[i];
+ unsigned output_format_size = mgr->ve->native_format_size[i];
+
+ /* Check for support. */
+ if (mgr->ve->ve[i].src_format == mgr->ve->native_format[i] &&
+ (mgr->caps.fetch_dword_unaligned ||
+ (vb->buffer_offset % 4 == 0 &&
+ vb->stride % 4 == 0 &&
+ mgr->ve->ve[i].src_offset % 4 == 0))) {
+ continue;
+ }
+
+ /* Workaround for translate: output floats instead of halfs. */
+ switch (output_format) {
+ case PIPE_FORMAT_R16_FLOAT:
+ output_format = PIPE_FORMAT_R32_FLOAT;
+ output_format_size = 4;
+ break;
+ case PIPE_FORMAT_R16G16_FLOAT:
+ output_format = PIPE_FORMAT_R32G32_FLOAT;
+ output_format_size = 8;
+ break;
+ case PIPE_FORMAT_R16G16B16_FLOAT:
+ output_format = PIPE_FORMAT_R32G32B32_FLOAT;
+ output_format_size = 12;
+ break;
+ case PIPE_FORMAT_R16G16B16A16_FLOAT:
+ output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+ output_format_size = 16;
+ break;
+ default:;
+ }
+
+ /* Add this vertex element. */
+ te = &key.element[key.nr_elements];
+ /*te->type;
+ te->instance_divisor;*/
+ te->input_buffer = mgr->ve->ve[i].vertex_buffer_index;
+ te->input_format = mgr->ve->ve[i].src_format;
+ te->input_offset = mgr->ve->ve[i].src_offset;
+ te->output_format = output_format;
+ te->output_offset = key.output_stride;
+
+ key.output_stride += output_format_size;
+ vb_translated[mgr->ve->ve[i].vertex_buffer_index] = TRUE;
+ tr_elem_index[i] = key.nr_elements;
+ key.nr_elements++;
+ }
+
+ /* Get a translate object. */
+ tr = translate_cache_find(mgr->translate_cache, &key);
+
+ /* Map buffers we want to translate. */
+ for (i = 0; i < mgr->b.nr_vertex_buffers; i++) {
+ if (vb_translated[i]) {
+ struct pipe_vertex_buffer *vb = &mgr->b.vertex_buffer[i];
+
+ vb_map[i] = pipe_buffer_map(mgr->pipe, vb->buffer,
+ PIPE_TRANSFER_READ, &vb_transfer[i]);
+
+ tr->set_buffer(tr, i,
+ vb_map[i] + vb->buffer_offset + vb->stride * min_index,
+ vb->stride, ~0);
+ }
+ }
+
+ /* Create and map the output buffer. */
+ num_verts = max_index + 1 - min_index;
+
+ u_upload_alloc(mgr->b.uploader,
+ key.output_stride * min_index,
+ key.output_stride * num_verts,
+ &out_offset, &out_buffer, upload_flushed,
+ (void**)&out_map);
+
+ out_offset -= key.output_stride * min_index;
+
+ /* Translate. */
+ tr->run(tr, 0, num_verts, 0, out_map);
+
+ /* Unmap all buffers. */
+ for (i = 0; i < mgr->b.nr_vertex_buffers; i++) {
+ if (vb_translated[i]) {
+ pipe_buffer_unmap(mgr->pipe, vb_transfer[i]);
+ }
+ }
+
+ /* Setup the new vertex buffer in the first free slot. */
+ mgr->translate_vb_slot = ~0;
+ for (i = 0; i < PIPE_MAX_ATTRIBS; i++) {
+ if (!mgr->b.vertex_buffer[i].buffer) {
+ mgr->translate_vb_slot = i;
+
+ if (i >= mgr->b.nr_vertex_buffers) {
+ mgr->b.nr_real_vertex_buffers = i+1;
+ }
+ break;
+ }
+ }
+
+ if (mgr->translate_vb_slot != ~0) {
+ /* Setup the new vertex buffer. */
+ pipe_resource_reference(
+ &mgr->b.real_vertex_buffer[mgr->translate_vb_slot], out_buffer);
+ mgr->b.vertex_buffer[mgr->translate_vb_slot].buffer_offset = out_offset;
+ mgr->b.vertex_buffer[mgr->translate_vb_slot].stride = key.output_stride;
+
+ /* Setup new vertex elements. */
+ for (i = 0; i < mgr->ve->count; i++) {
+ if (tr_elem_index[i] < key.nr_elements) {
+ te = &key.element[tr_elem_index[i]];
+ new_velems[i].instance_divisor = mgr->ve->ve[i].instance_divisor;
+ new_velems[i].src_format = te->output_format;
+ new_velems[i].src_offset = te->output_offset;
+ new_velems[i].vertex_buffer_index = mgr->translate_vb_slot;
+ } else {
+ memcpy(&new_velems[i], &mgr->ve->ve[i],
+ sizeof(struct pipe_vertex_element));
+ }
+ }
+
+ mgr->fallback_ve =
+ mgr->pipe->create_vertex_elements_state(mgr->pipe, mgr->ve->count,
+ new_velems);
+
+ /* Preserve saved_ve. */
+ mgr->ve_binding_lock = TRUE;
+ mgr->pipe->bind_vertex_elements_state(mgr->pipe, mgr->fallback_ve);
+ mgr->ve_binding_lock = FALSE;
+ }
+
+ pipe_resource_reference(&out_buffer, NULL);
+}
+
+static void u_vbuf_translate_end(struct u_vbuf_mgr_priv *mgr)
+{
+ if (mgr->fallback_ve == NULL) {
+ return;
+ }
+
+ /* Restore vertex elements. */
+ /* Note that saved_ve will be overwritten in bind_vertex_elements_state. */
+ mgr->pipe->bind_vertex_elements_state(mgr->pipe, mgr->saved_ve);
+ mgr->pipe->delete_vertex_elements_state(mgr->pipe, mgr->fallback_ve);
+ mgr->fallback_ve = NULL;
+
+ /* Delete the now-unused VBO. */
+ pipe_resource_reference(&mgr->b.real_vertex_buffer[mgr->translate_vb_slot],
+ NULL);
+ mgr->b.nr_real_vertex_buffers = mgr->b.nr_vertex_buffers;
+}
+
+#define FORMAT_REPLACE(what, withwhat) \
+ case PIPE_FORMAT_##what: format = PIPE_FORMAT_##withwhat; break
+
+struct u_vbuf_mgr_elements *
+u_vbuf_mgr_create_vertex_elements(struct u_vbuf_mgr *mgrb,
+ unsigned count,
+ const struct pipe_vertex_element *attribs,
+ struct pipe_vertex_element *native_attribs)
+{
+ struct u_vbuf_mgr_priv *mgr = (struct u_vbuf_mgr_priv*)mgrb;
+ unsigned i;
+ struct u_vbuf_mgr_elements *ve = CALLOC_STRUCT(u_vbuf_mgr_elements);
+
+ ve->count = count;
+
+ if (!count) {
+ return ve;
+ }
+
+ memcpy(ve->ve, attribs, sizeof(struct pipe_vertex_element) * count);
+ memcpy(native_attribs, attribs, sizeof(struct pipe_vertex_element) * count);
+
+ /* Set the best native format in case the original format is not
+ * supported. */
+ for (i = 0; i < count; i++) {
+ enum pipe_format format = ve->ve[i].src_format;
+
+ /* Choose a native format.
+ * For now we don't care about the alignment, that's going to
+ * be sorted out later. */
+ if (!mgr->caps.format_fixed32) {
+ switch (format) {
+ FORMAT_REPLACE(R32_FIXED, R32_FLOAT);
+ FORMAT_REPLACE(R32G32_FIXED, R32G32_FLOAT);
+ FORMAT_REPLACE(R32G32B32_FIXED, R32G32B32_FLOAT);
+ FORMAT_REPLACE(R32G32B32A32_FIXED, R32G32B32A32_FLOAT);
+ default:;
+ }
+ }
+ if (!mgr->caps.format_float16) {
+ switch (format) {
+ FORMAT_REPLACE(R16_FLOAT, R32_FLOAT);
+ FORMAT_REPLACE(R16G16_FLOAT, R32G32_FLOAT);
+ FORMAT_REPLACE(R16G16B16_FLOAT, R32G32B32_FLOAT);
+ FORMAT_REPLACE(R16G16B16A16_FLOAT, R32G32B32A32_FLOAT);
+ default:;
+ }
+ }
+ if (!mgr->caps.format_float64) {
+ switch (format) {
+ FORMAT_REPLACE(R64_FLOAT, R32_FLOAT);
+ FORMAT_REPLACE(R64G64_FLOAT, R32G32_FLOAT);
+ FORMAT_REPLACE(R64G64B64_FLOAT, R32G32B32_FLOAT);
+ FORMAT_REPLACE(R64G64B64A64_FLOAT, R32G32B32A32_FLOAT);
+ default:;
+ }
+ }
+ if (!mgr->caps.format_norm32) {
+ switch (format) {
+ FORMAT_REPLACE(R32_UNORM, R32_FLOAT);
+ FORMAT_REPLACE(R32G32_UNORM, R32G32_FLOAT);
+ FORMAT_REPLACE(R32G32B32_UNORM, R32G32B32_FLOAT);
+ FORMAT_REPLACE(R32G32B32A32_UNORM, R32G32B32A32_FLOAT);
+ FORMAT_REPLACE(R32_SNORM, R32_FLOAT);
+ FORMAT_REPLACE(R32G32_SNORM, R32G32_FLOAT);
+ FORMAT_REPLACE(R32G32B32_SNORM, R32G32B32_FLOAT);
+ FORMAT_REPLACE(R32G32B32A32_SNORM, R32G32B32A32_FLOAT);
+ default:;
+ }
+ }
+ if (!mgr->caps.format_scaled32) {
+ switch (format) {
+ FORMAT_REPLACE(R32_USCALED, R32_FLOAT);
+ FORMAT_REPLACE(R32G32_USCALED, R32G32_FLOAT);
+ FORMAT_REPLACE(R32G32B32_USCALED, R32G32B32_FLOAT);
+ FORMAT_REPLACE(R32G32B32A32_USCALED,R32G32B32A32_FLOAT);
+ FORMAT_REPLACE(R32_SSCALED, R32_FLOAT);
+ FORMAT_REPLACE(R32G32_SSCALED, R32G32_FLOAT);
+ FORMAT_REPLACE(R32G32B32_SSCALED, R32G32B32_FLOAT);
+ FORMAT_REPLACE(R32G32B32A32_SSCALED,R32G32B32A32_FLOAT);
+ default:;
+ }
+ }
+
+ native_attribs[i].src_format = format;
+ ve->native_format[i] = format;
+ ve->native_format_size[i] =
+ util_format_get_blocksize(ve->native_format[i]);
+
+ ve->incompatible_layout =
+ ve->incompatible_layout ||
+ ve->ve[i].src_format != ve->native_format[i] ||
+ (!mgr->caps.fetch_dword_unaligned && ve->ve[i].src_offset % 4 != 0);
+ }
+
+ /* Align the formats to the size of DWORD if needed. */
+ if (!mgr->caps.fetch_dword_unaligned) {
+ for (i = 0; i < count; i++) {
+ ve->native_format_size[i] = align(ve->native_format_size[i], 4);
+ }
+ }
+
+ return ve;
+}
+
+void u_vbuf_mgr_bind_vertex_elements(struct u_vbuf_mgr *mgrb,
+ void *cso,
+ struct u_vbuf_mgr_elements *ve)
+{
+ struct u_vbuf_mgr_priv *mgr = (struct u_vbuf_mgr_priv*)mgrb;
+
+ if (!cso) {
+ return;
+ }
+
+ if (!mgr->ve_binding_lock) {
+ mgr->saved_ve = cso;
+ mgr->ve = ve;
+ }
+}
+
+void u_vbuf_mgr_destroy_vertex_elements(struct u_vbuf_mgr *mgr,
+ struct u_vbuf_mgr_elements *ve)
+{
+ FREE(ve);
+}
+
+void u_vbuf_mgr_set_vertex_buffers(struct u_vbuf_mgr *mgrb,
+ unsigned count,
+ const struct pipe_vertex_buffer *bufs)
+{
+ struct u_vbuf_mgr_priv *mgr = (struct u_vbuf_mgr_priv*)mgrb;
+ unsigned i;
+
+ mgr->b.max_index = ~0;
+ mgr->any_user_vbs = FALSE;
+ mgr->incompatible_vb_layout = FALSE;
+
+ if (!mgr->caps.fetch_dword_unaligned) {
+ /* Check if the strides and offsets are aligned to the size of DWORD. */
+ for (i = 0; i < count; i++) {
+ if (bufs[i].buffer) {
+ if (bufs[i].stride % 4 != 0 ||
+ bufs[i].buffer_offset % 4 != 0) {
+ mgr->incompatible_vb_layout = TRUE;
+ break;
+ }
+ }
+ }
+ }
+
+ for (i = 0; i < count; i++) {
+ const struct pipe_vertex_buffer *vb = &bufs[i];
+
+ pipe_resource_reference(&mgr->b.vertex_buffer[i].buffer, vb->buffer);
+ pipe_resource_reference(&mgr->b.real_vertex_buffer[i], NULL);
+
+ if (u_vbuf_resource(vb->buffer)->user_ptr) {
+ mgr->any_user_vbs = TRUE;
+ continue;
+ }
+
+ pipe_resource_reference(&mgr->b.real_vertex_buffer[i], vb->buffer);
+
+ /* The stride of zero means we will be fetching only the first
+ * vertex, so don't care about max_index. */
+ if (!vb->stride) {
+ continue;
+ }
+
+ /* Update the maximum index. */
+ mgr->b.max_index =
+ MIN2(mgr->b.max_index,
+ (vb->buffer->width0 - vb->buffer_offset) / vb->stride);
+ }
+
+ for (; i < mgr->b.nr_real_vertex_buffers; i++) {
+ pipe_resource_reference(&mgr->b.vertex_buffer[i].buffer, NULL);
+ pipe_resource_reference(&mgr->b.real_vertex_buffer[i], NULL);
+ }
+
+ memcpy(mgr->b.vertex_buffer, bufs,
+ sizeof(struct pipe_vertex_buffer) * count);
+
+ mgr->b.nr_vertex_buffers = count;
+ mgr->b.nr_real_vertex_buffers = count;
+}
+
+static void u_vbuf_upload_buffers(struct u_vbuf_mgr_priv *mgr,
+ int min_index, int max_index,
+ boolean *upload_flushed)
+{
+ int i, nr = mgr->ve->count;
+ unsigned count = max_index + 1 - min_index;
+ boolean uploaded[PIPE_MAX_ATTRIBS] = {0};
+
+ for (i = 0; i < nr; i++) {
+ unsigned index = mgr->ve->ve[i].vertex_buffer_index;
+ struct pipe_vertex_buffer *vb = &mgr->b.vertex_buffer[index];
+
+ if (vb->buffer &&
+ u_vbuf_resource(vb->buffer)->user_ptr &&
+ !uploaded[index]) {
+ unsigned first, size;
+ boolean flushed;
+
+ if (vb->stride) {
+ first = vb->stride * min_index;
+ size = vb->stride * count;
+ } else {
+ first = 0;
+ size = mgr->ve->native_format_size[i];
+ }
+
+ u_upload_data(mgr->b.uploader, first, size,
+ u_vbuf_resource(vb->buffer)->user_ptr + first,
+ &vb->buffer_offset,
+ &mgr->b.real_vertex_buffer[index],
+ &flushed);
+
+ vb->buffer_offset -= first;
+
+ uploaded[index] = TRUE;
+ *upload_flushed = *upload_flushed || flushed;
+ } else {
+ assert(mgr->b.real_vertex_buffer[index]);
+ }
+ }
+}
+
+void u_vbuf_mgr_draw_begin(struct u_vbuf_mgr *mgrb,
+ const struct pipe_draw_info *info,
+ boolean *buffers_updated,
+ boolean *uploader_flushed)
+{
+ struct u_vbuf_mgr_priv *mgr = (struct u_vbuf_mgr_priv*)mgrb;
+ boolean bufs_updated = FALSE, upload_flushed = FALSE;
+ int min_index, max_index;
+
+ min_index = info->min_index - info->index_bias;
+ max_index = info->max_index - info->index_bias;
+
+ /* Translate vertices with non-native layouts or formats. */
+ if (mgr->incompatible_vb_layout || mgr->ve->incompatible_layout) {
+ u_vbuf_translate_begin(mgr, min_index, max_index, &upload_flushed);
+
+ if (mgr->fallback_ve) {
+ bufs_updated = TRUE;
+ }
+ }
+
+ /* Upload user buffers. */
+ if (mgr->any_user_vbs) {
+ u_vbuf_upload_buffers(mgr, min_index, max_index, &upload_flushed);
+ bufs_updated = TRUE;
+ }
+
+ /* Set the return values. */
+ if (buffers_updated) {
+ *buffers_updated = bufs_updated;
+ }
+ if (uploader_flushed) {
+ *uploader_flushed = upload_flushed;
+ }
+}
+
+void u_vbuf_mgr_draw_end(struct u_vbuf_mgr *mgrb)
+{
+ struct u_vbuf_mgr_priv *mgr = (struct u_vbuf_mgr_priv*)mgrb;
+
+ if (mgr->fallback_ve) {
+ u_vbuf_translate_end(mgr);
+ }
+}
diff --git a/src/gallium/auxiliary/util/u_vbuf_mgr.h b/src/gallium/auxiliary/util/u_vbuf_mgr.h
new file mode 100644
index 00000000000..8b241854c83
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_vbuf_mgr.h
@@ -0,0 +1,121 @@
+/**************************************************************************
+ *
+ * Copyright 2011 Marek Olšák <[email protected]>
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef U_VBUF_MGR_H
+#define U_VBUF_MGR_H
+
+/* This module builds upon u_upload_mgr and translate_cache and takes care of
+ * user buffer uploads and vertex format fallbacks. It's designed
+ * for the drivers which don't always use the Draw module. (e.g. for HWTCL)
+ */
+
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+#include "util/u_transfer.h"
+
+/* The manager.
+ * This structure should also be used to access vertex buffers
+ * from a driver. */
+struct u_vbuf_mgr {
+ /* This is what was set in set_vertex_buffers.
+ * May contain user buffers. */
+ struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
+ unsigned nr_vertex_buffers;
+
+ /* Contains only real vertex buffers.
+ * Hardware drivers should use real_vertex_buffers[i]
+ * instead of vertex_buffers[i].buffer. */
+ struct pipe_resource *real_vertex_buffer[PIPE_MAX_ATTRIBS];
+ int nr_real_vertex_buffers;
+
+ /* Precomputed max_index for hardware vertex buffers. */
+ int max_index;
+
+ /* This uploader can optionally be used by the driver.
+ *
+ * Allowed functions:
+ * - u_upload_alloc
+ * - u_upload_data
+ * - u_upload_buffer
+ * - u_upload_flush */
+ struct u_upload_mgr *uploader;
+};
+
+struct u_vbuf_resource {
+ struct u_resource b;
+ uint8_t *user_ptr;
+};
+
+/* Opaque type containing information about vertex elements for the manager. */
+struct u_vbuf_mgr_elements;
+
+enum u_fetch_alignment {
+ U_VERTEX_FETCH_BYTE_ALIGNED,
+ U_VERTEX_FETCH_DWORD_ALIGNED
+};
+
+
+struct u_vbuf_mgr *
+u_vbuf_mgr_create(struct pipe_context *pipe,
+ unsigned upload_buffer_size,
+ unsigned upload_buffer_alignment,
+ unsigned upload_buffer_bind,
+ enum u_fetch_alignment fetch_alignment);
+
+void u_vbuf_mgr_destroy(struct u_vbuf_mgr *mgr);
+
+struct u_vbuf_mgr_elements *
+u_vbuf_mgr_create_vertex_elements(struct u_vbuf_mgr *mgr,
+ unsigned count,
+ const struct pipe_vertex_element *attrs,
+ struct pipe_vertex_element *native_attrs);
+
+void u_vbuf_mgr_bind_vertex_elements(struct u_vbuf_mgr *mgr,
+ void *cso,
+ struct u_vbuf_mgr_elements *ve);
+
+void u_vbuf_mgr_destroy_vertex_elements(struct u_vbuf_mgr *mgr,
+ struct u_vbuf_mgr_elements *ve);
+
+void u_vbuf_mgr_set_vertex_buffers(struct u_vbuf_mgr *mgr,
+ unsigned count,
+ const struct pipe_vertex_buffer *bufs);
+
+void u_vbuf_mgr_draw_begin(struct u_vbuf_mgr *mgr,
+ const struct pipe_draw_info *info,
+ boolean *buffers_updated,
+ boolean *uploader_flushed);
+
+void u_vbuf_mgr_draw_end(struct u_vbuf_mgr *mgr);
+
+
+static INLINE struct u_vbuf_resource *u_vbuf_resource(struct pipe_resource *r)
+{
+ return (struct u_vbuf_resource*)r;
+}
+
+#endif