/contrib/sdk/sources/Mesa/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 |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_atomic.h |
---|
0,0 → 1,349 |
/** |
* Many similar implementations exist. See for example libwsbm |
* or the linux kernel include/atomic.h |
* |
* No copyright claimed on this file. |
* |
*/ |
#ifndef U_ATOMIC_H |
#define U_ATOMIC_H |
#include "pipe/p_compiler.h" |
#include "pipe/p_defines.h" |
/* Favor OS-provided implementations. |
* |
* Where no OS-provided implementation is available, fall back to |
* locally coded assembly, compiler intrinsic or ultimately a |
* mutex-based implementation. |
*/ |
#if defined(PIPE_OS_SOLARIS) |
#define PIPE_ATOMIC_OS_SOLARIS |
#elif defined(PIPE_CC_MSVC) |
#define PIPE_ATOMIC_MSVC_INTRINSIC |
#elif (defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86)) |
#define PIPE_ATOMIC_ASM_MSVC_X86 |
#elif (defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86)) |
#define PIPE_ATOMIC_ASM_GCC_X86 |
#elif (defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86_64)) |
#define PIPE_ATOMIC_ASM_GCC_X86_64 |
#elif defined(PIPE_CC_GCC) && (PIPE_CC_GCC_VERSION >= 401) |
#define PIPE_ATOMIC_GCC_INTRINSIC |
#else |
#error "Unsupported platform" |
#endif |
#if defined(PIPE_ATOMIC_ASM_GCC_X86_64) |
#define PIPE_ATOMIC "GCC x86_64 assembly" |
#ifdef __cplusplus |
extern "C" { |
#endif |
#define p_atomic_set(_v, _i) (*(_v) = (_i)) |
#define p_atomic_read(_v) (*(_v)) |
static INLINE boolean |
p_atomic_dec_zero(int32_t *v) |
{ |
unsigned char c; |
__asm__ __volatile__("lock; decl %0; sete %1":"+m"(*v), "=qm"(c) |
::"memory"); |
return c != 0; |
} |
static INLINE void |
p_atomic_inc(int32_t *v) |
{ |
__asm__ __volatile__("lock; incl %0":"+m"(*v)); |
} |
static INLINE void |
p_atomic_dec(int32_t *v) |
{ |
__asm__ __volatile__("lock; decl %0":"+m"(*v)); |
} |
static INLINE int32_t |
p_atomic_cmpxchg(int32_t *v, int32_t old, int32_t _new) |
{ |
return __sync_val_compare_and_swap(v, old, _new); |
} |
#ifdef __cplusplus |
} |
#endif |
#endif /* PIPE_ATOMIC_ASM_GCC_X86_64 */ |
#if defined(PIPE_ATOMIC_ASM_GCC_X86) |
#define PIPE_ATOMIC "GCC x86 assembly" |
#ifdef __cplusplus |
extern "C" { |
#endif |
#define p_atomic_set(_v, _i) (*(_v) = (_i)) |
#define p_atomic_read(_v) (*(_v)) |
static INLINE boolean |
p_atomic_dec_zero(int32_t *v) |
{ |
unsigned char c; |
__asm__ __volatile__("lock; decl %0; sete %1":"+m"(*v), "=qm"(c) |
::"memory"); |
return c != 0; |
} |
static INLINE void |
p_atomic_inc(int32_t *v) |
{ |
__asm__ __volatile__("lock; incl %0":"+m"(*v)); |
} |
static INLINE void |
p_atomic_dec(int32_t *v) |
{ |
__asm__ __volatile__("lock; decl %0":"+m"(*v)); |
} |
static INLINE int32_t |
p_atomic_cmpxchg(int32_t *v, int32_t old, int32_t _new) |
{ |
return __sync_val_compare_and_swap(v, old, _new); |
} |
#ifdef __cplusplus |
} |
#endif |
#endif |
/* Implementation using GCC-provided synchronization intrinsics |
*/ |
#if defined(PIPE_ATOMIC_GCC_INTRINSIC) |
#define PIPE_ATOMIC "GCC Sync Intrinsics" |
#ifdef __cplusplus |
extern "C" { |
#endif |
#define p_atomic_set(_v, _i) (*(_v) = (_i)) |
#define p_atomic_read(_v) (*(_v)) |
static INLINE boolean |
p_atomic_dec_zero(int32_t *v) |
{ |
return (__sync_sub_and_fetch(v, 1) == 0); |
} |
static INLINE void |
p_atomic_inc(int32_t *v) |
{ |
(void) __sync_add_and_fetch(v, 1); |
} |
static INLINE void |
p_atomic_dec(int32_t *v) |
{ |
(void) __sync_sub_and_fetch(v, 1); |
} |
static INLINE int32_t |
p_atomic_cmpxchg(int32_t *v, int32_t old, int32_t _new) |
{ |
return __sync_val_compare_and_swap(v, old, _new); |
} |
#ifdef __cplusplus |
} |
#endif |
#endif |
/* Unlocked version for single threaded environments, such as some |
* windows kernel modules. |
*/ |
#if defined(PIPE_ATOMIC_OS_UNLOCKED) |
#define PIPE_ATOMIC "Unlocked" |
#define p_atomic_set(_v, _i) (*(_v) = (_i)) |
#define p_atomic_read(_v) (*(_v)) |
#define p_atomic_dec_zero(_v) ((boolean) --(*(_v))) |
#define p_atomic_inc(_v) ((void) (*(_v))++) |
#define p_atomic_dec(_v) ((void) (*(_v))--) |
#define p_atomic_cmpxchg(_v, old, _new) (*(_v) == old ? *(_v) = (_new) : *(_v)) |
#endif |
/* Locally coded assembly for MSVC on x86: |
*/ |
#if defined(PIPE_ATOMIC_ASM_MSVC_X86) |
#define PIPE_ATOMIC "MSVC x86 assembly" |
#ifdef __cplusplus |
extern "C" { |
#endif |
#define p_atomic_set(_v, _i) (*(_v) = (_i)) |
#define p_atomic_read(_v) (*(_v)) |
static INLINE boolean |
p_atomic_dec_zero(int32_t *v) |
{ |
unsigned char c; |
__asm { |
mov eax, [v] |
lock dec dword ptr [eax] |
sete byte ptr [c] |
} |
return c != 0; |
} |
static INLINE void |
p_atomic_inc(int32_t *v) |
{ |
__asm { |
mov eax, [v] |
lock inc dword ptr [eax] |
} |
} |
static INLINE void |
p_atomic_dec(int32_t *v) |
{ |
__asm { |
mov eax, [v] |
lock dec dword ptr [eax] |
} |
} |
static INLINE int32_t |
p_atomic_cmpxchg(int32_t *v, int32_t old, int32_t _new) |
{ |
int32_t orig; |
__asm { |
mov ecx, [v] |
mov eax, [old] |
mov edx, [_new] |
lock cmpxchg [ecx], edx |
mov [orig], eax |
} |
return orig; |
} |
#ifdef __cplusplus |
} |
#endif |
#endif |
#if defined(PIPE_ATOMIC_MSVC_INTRINSIC) |
#define PIPE_ATOMIC "MSVC Intrinsics" |
#include <intrin.h> |
#pragma intrinsic(_InterlockedIncrement) |
#pragma intrinsic(_InterlockedDecrement) |
#pragma intrinsic(_InterlockedCompareExchange) |
#ifdef __cplusplus |
extern "C" { |
#endif |
#define p_atomic_set(_v, _i) (*(_v) = (_i)) |
#define p_atomic_read(_v) (*(_v)) |
static INLINE boolean |
p_atomic_dec_zero(int32_t *v) |
{ |
return _InterlockedDecrement((long *)v) == 0; |
} |
static INLINE void |
p_atomic_inc(int32_t *v) |
{ |
_InterlockedIncrement((long *)v); |
} |
static INLINE void |
p_atomic_dec(int32_t *v) |
{ |
_InterlockedDecrement((long *)v); |
} |
static INLINE int32_t |
p_atomic_cmpxchg(int32_t *v, int32_t old, int32_t _new) |
{ |
return _InterlockedCompareExchange((long *)v, _new, old); |
} |
#ifdef __cplusplus |
} |
#endif |
#endif |
#if defined(PIPE_ATOMIC_OS_SOLARIS) |
#define PIPE_ATOMIC "Solaris OS atomic functions" |
#include <atomic.h> |
#ifdef __cplusplus |
extern "C" { |
#endif |
#define p_atomic_set(_v, _i) (*(_v) = (_i)) |
#define p_atomic_read(_v) (*(_v)) |
static INLINE boolean |
p_atomic_dec_zero(int32_t *v) |
{ |
uint32_t n = atomic_dec_32_nv((uint32_t *) v); |
return n != 0; |
} |
#define p_atomic_inc(_v) atomic_inc_32((uint32_t *) _v) |
#define p_atomic_dec(_v) atomic_dec_32((uint32_t *) _v) |
#define p_atomic_cmpxchg(_v, _old, _new) \ |
atomic_cas_32( (uint32_t *) _v, (uint32_t) _old, (uint32_t) _new) |
#ifdef __cplusplus |
} |
#endif |
#endif |
#ifndef PIPE_ATOMIC |
#error "No pipe_atomic implementation selected" |
#endif |
#endif /* U_ATOMIC_H */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_bitmask.c |
---|
0,0 → 1,328 |
/************************************************************************** |
* |
* Copyright 2009 VMware, Inc. |
* 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 VMWARE 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. |
* |
**************************************************************************/ |
/** |
* @file |
* Generic bitmask implementation. |
* |
* @author Jose Fonseca <jfonseca@vmware.com> |
*/ |
#include "pipe/p_compiler.h" |
#include "util/u_debug.h" |
#include "util/u_memory.h" |
#include "util/u_bitmask.h" |
typedef uint32_t util_bitmask_word; |
#define UTIL_BITMASK_INITIAL_WORDS 16 |
#define UTIL_BITMASK_BITS_PER_BYTE 8 |
#define UTIL_BITMASK_BITS_PER_WORD (sizeof(util_bitmask_word) * UTIL_BITMASK_BITS_PER_BYTE) |
struct util_bitmask |
{ |
util_bitmask_word *words; |
/** Number of bits we can currently hold */ |
unsigned size; |
/** Number of consecutive bits set at the start of the bitmask */ |
unsigned filled; |
}; |
struct util_bitmask * |
util_bitmask_create(void) |
{ |
struct util_bitmask *bm; |
bm = MALLOC_STRUCT(util_bitmask); |
if(!bm) |
return NULL; |
bm->words = (util_bitmask_word *)CALLOC(UTIL_BITMASK_INITIAL_WORDS, sizeof(util_bitmask_word)); |
if(!bm->words) { |
FREE(bm); |
return NULL; |
} |
bm->size = UTIL_BITMASK_INITIAL_WORDS * UTIL_BITMASK_BITS_PER_WORD; |
bm->filled = 0; |
return bm; |
} |
/** |
* Resize the bitmask if necessary |
*/ |
static INLINE boolean |
util_bitmask_resize(struct util_bitmask *bm, |
unsigned minimum_index) |
{ |
unsigned minimum_size = minimum_index + 1; |
unsigned new_size; |
util_bitmask_word *new_words; |
/* Check integer overflow */ |
if(!minimum_size) |
return FALSE; |
if(bm->size >= minimum_size) |
return TRUE; |
assert(bm->size % UTIL_BITMASK_BITS_PER_WORD == 0); |
new_size = bm->size; |
while(new_size < minimum_size) { |
new_size *= 2; |
/* Check integer overflow */ |
if(new_size < bm->size) |
return FALSE; |
} |
assert(new_size); |
assert(new_size % UTIL_BITMASK_BITS_PER_WORD == 0); |
new_words = (util_bitmask_word *)REALLOC((void *)bm->words, |
bm->size / UTIL_BITMASK_BITS_PER_BYTE, |
new_size / UTIL_BITMASK_BITS_PER_BYTE); |
if(!new_words) |
return FALSE; |
memset(new_words + bm->size/UTIL_BITMASK_BITS_PER_WORD, |
0, |
(new_size - bm->size)/UTIL_BITMASK_BITS_PER_BYTE); |
bm->size = new_size; |
bm->words = new_words; |
return TRUE; |
} |
/** |
* Lazily update the filled. |
*/ |
static INLINE void |
util_bitmask_filled_set(struct util_bitmask *bm, |
unsigned index) |
{ |
assert(bm->filled <= bm->size); |
assert(index < bm->size); |
if(index == bm->filled) { |
++bm->filled; |
assert(bm->filled <= bm->size); |
} |
} |
static INLINE void |
util_bitmask_filled_unset(struct util_bitmask *bm, |
unsigned index) |
{ |
assert(bm->filled <= bm->size); |
assert(index < bm->size); |
if(index < bm->filled) |
bm->filled = index; |
} |
unsigned |
util_bitmask_add(struct util_bitmask *bm) |
{ |
unsigned word; |
unsigned bit; |
util_bitmask_word mask; |
assert(bm); |
/* linear search for an empty index */ |
word = bm->filled / UTIL_BITMASK_BITS_PER_WORD; |
bit = bm->filled % UTIL_BITMASK_BITS_PER_WORD; |
mask = 1 << bit; |
while(word < bm->size / UTIL_BITMASK_BITS_PER_WORD) { |
while(bit < UTIL_BITMASK_BITS_PER_WORD) { |
if(!(bm->words[word] & mask)) |
goto found; |
++bm->filled; |
++bit; |
mask <<= 1; |
} |
++word; |
bit = 0; |
mask = 1; |
} |
found: |
/* grow the bitmask if necessary */ |
if(!util_bitmask_resize(bm, bm->filled)) |
return UTIL_BITMASK_INVALID_INDEX; |
assert(!(bm->words[word] & mask)); |
bm->words[word] |= mask; |
return bm->filled++; |
} |
unsigned |
util_bitmask_set(struct util_bitmask *bm, |
unsigned index) |
{ |
unsigned word; |
unsigned bit; |
util_bitmask_word mask; |
assert(bm); |
/* grow the bitmask if necessary */ |
if(!util_bitmask_resize(bm, index)) |
return UTIL_BITMASK_INVALID_INDEX; |
word = index / UTIL_BITMASK_BITS_PER_WORD; |
bit = index % UTIL_BITMASK_BITS_PER_WORD; |
mask = 1 << bit; |
bm->words[word] |= mask; |
util_bitmask_filled_set(bm, index); |
return index; |
} |
void |
util_bitmask_clear(struct util_bitmask *bm, |
unsigned index) |
{ |
unsigned word; |
unsigned bit; |
util_bitmask_word mask; |
assert(bm); |
if(index >= bm->size) |
return; |
word = index / UTIL_BITMASK_BITS_PER_WORD; |
bit = index % UTIL_BITMASK_BITS_PER_WORD; |
mask = 1 << bit; |
bm->words[word] &= ~mask; |
util_bitmask_filled_unset(bm, index); |
} |
boolean |
util_bitmask_get(struct util_bitmask *bm, |
unsigned index) |
{ |
unsigned word = index / UTIL_BITMASK_BITS_PER_WORD; |
unsigned bit = index % UTIL_BITMASK_BITS_PER_WORD; |
util_bitmask_word mask = 1 << bit; |
assert(bm); |
if(index < bm->filled) { |
assert(bm->words[word] & mask); |
return TRUE; |
} |
if(index >= bm->size) |
return FALSE; |
if(bm->words[word] & mask) { |
util_bitmask_filled_set(bm, index); |
return TRUE; |
} |
else |
return FALSE; |
} |
unsigned |
util_bitmask_get_next_index(struct util_bitmask *bm, |
unsigned index) |
{ |
unsigned word = index / UTIL_BITMASK_BITS_PER_WORD; |
unsigned bit = index % UTIL_BITMASK_BITS_PER_WORD; |
util_bitmask_word mask = 1 << bit; |
if(index < bm->filled) { |
assert(bm->words[word] & mask); |
return index; |
} |
if(index >= bm->size) { |
return UTIL_BITMASK_INVALID_INDEX; |
} |
/* Do a linear search */ |
while(word < bm->size / UTIL_BITMASK_BITS_PER_WORD) { |
while(bit < UTIL_BITMASK_BITS_PER_WORD) { |
if(bm->words[word] & mask) { |
if(index == bm->filled) { |
++bm->filled; |
assert(bm->filled <= bm->size); |
} |
return index; |
} |
++index; |
++bit; |
mask <<= 1; |
} |
++word; |
bit = 0; |
mask = 1; |
} |
return UTIL_BITMASK_INVALID_INDEX; |
} |
unsigned |
util_bitmask_get_first_index(struct util_bitmask *bm) |
{ |
return util_bitmask_get_next_index(bm, 0); |
} |
void |
util_bitmask_destroy(struct util_bitmask *bm) |
{ |
assert(bm); |
FREE(bm->words); |
FREE(bm); |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_bitmask.h |
---|
0,0 → 1,117 |
/************************************************************************** |
* |
* Copyright 2009 VMware, Inc. |
* 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 VMWARE 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. |
* |
**************************************************************************/ |
/** |
* @file |
* Generic bitmask. |
* |
* @author Jose Fonseca <jfonseca@vmware.com> |
*/ |
#ifndef U_HANDLE_BITMASK_H_ |
#define U_HANDLE_BITMASK_H_ |
#include "pipe/p_compiler.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
#define UTIL_BITMASK_INVALID_INDEX (~0U) |
/** |
* Abstract data type to represent arbitrary set of bits. |
*/ |
struct util_bitmask; |
struct util_bitmask * |
util_bitmask_create(void); |
/** |
* Search a cleared bit and set it. |
* |
* It searches for the first cleared bit. |
* |
* Returns the bit index on success, or UTIL_BITMASK_INVALID_INDEX on out of |
* memory growing the bitmask. |
*/ |
unsigned |
util_bitmask_add(struct util_bitmask *bm); |
/** |
* Set a bit. |
* |
* Returns the input index on success, or UTIL_BITMASK_INVALID_INDEX on out of |
* memory growing the bitmask. |
*/ |
unsigned |
util_bitmask_set(struct util_bitmask *bm, |
unsigned index); |
void |
util_bitmask_clear(struct util_bitmask *bm, |
unsigned index); |
boolean |
util_bitmask_get(struct util_bitmask *bm, |
unsigned index); |
void |
util_bitmask_destroy(struct util_bitmask *bm); |
/** |
* Search for the first set bit. |
* |
* Returns UTIL_BITMASK_INVALID_INDEX if a set bit cannot be found. |
*/ |
unsigned |
util_bitmask_get_first_index(struct util_bitmask *bm); |
/** |
* Search for the first set bit, starting from the giving index. |
* |
* Returns UTIL_BITMASK_INVALID_INDEX if a set bit cannot be found. |
*/ |
unsigned |
util_bitmask_get_next_index(struct util_bitmask *bm, |
unsigned index); |
#ifdef __cplusplus |
} |
#endif |
#endif /* U_HANDLE_BITMASK_H_ */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_blit.c |
---|
0,0 → 1,954 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* 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 TUNGSTEN GRAPHICS 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. |
* |
**************************************************************************/ |
/** |
* @file |
* Copy/blit pixel rect between surfaces |
* |
* @author Brian Paul |
*/ |
#include "pipe/p_context.h" |
#include "util/u_debug.h" |
#include "pipe/p_defines.h" |
#include "util/u_inlines.h" |
#include "pipe/p_shader_tokens.h" |
#include "pipe/p_state.h" |
#include "util/u_blit.h" |
#include "util/u_draw_quad.h" |
#include "util/u_format.h" |
#include "util/u_math.h" |
#include "util/u_memory.h" |
#include "util/u_sampler.h" |
#include "util/u_simple_shaders.h" |
#include "cso_cache/cso_context.h" |
struct blit_state |
{ |
struct pipe_context *pipe; |
struct cso_context *cso; |
struct pipe_blend_state blend_write_color, blend_keep_color; |
struct pipe_depth_stencil_alpha_state dsa_keep_depthstencil; |
struct pipe_depth_stencil_alpha_state dsa_write_depthstencil; |
struct pipe_depth_stencil_alpha_state dsa_write_depth; |
struct pipe_depth_stencil_alpha_state dsa_write_stencil; |
struct pipe_rasterizer_state rasterizer; |
struct pipe_sampler_state sampler; |
struct pipe_viewport_state viewport; |
struct pipe_vertex_element velem[2]; |
enum pipe_texture_target internal_target; |
void *vs; |
void *fs[PIPE_MAX_TEXTURE_TYPES][TGSI_WRITEMASK_XYZW + 1]; |
void *fs_depthstencil[PIPE_MAX_TEXTURE_TYPES]; |
void *fs_depth[PIPE_MAX_TEXTURE_TYPES]; |
void *fs_stencil[PIPE_MAX_TEXTURE_TYPES]; |
struct pipe_resource *vbuf; /**< quad vertices */ |
unsigned vbuf_slot; |
float vertices[4][2][4]; /**< vertex/texcoords for quad */ |
boolean has_stencil_export; |
}; |
/** |
* Create state object for blit. |
* Intended to be created once and re-used for many blit() calls. |
*/ |
struct blit_state * |
util_create_blit(struct pipe_context *pipe, struct cso_context *cso) |
{ |
struct blit_state *ctx; |
uint i; |
ctx = CALLOC_STRUCT(blit_state); |
if (!ctx) |
return NULL; |
ctx->pipe = pipe; |
ctx->cso = cso; |
/* disabled blending/masking */ |
ctx->blend_write_color.rt[0].colormask = PIPE_MASK_RGBA; |
/* depth stencil states */ |
ctx->dsa_write_depth.depth.enabled = 1; |
ctx->dsa_write_depth.depth.writemask = 1; |
ctx->dsa_write_depth.depth.func = PIPE_FUNC_ALWAYS; |
ctx->dsa_write_stencil.stencil[0].enabled = 1; |
ctx->dsa_write_stencil.stencil[0].func = PIPE_FUNC_ALWAYS; |
ctx->dsa_write_stencil.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE; |
ctx->dsa_write_stencil.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE; |
ctx->dsa_write_stencil.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE; |
ctx->dsa_write_stencil.stencil[0].valuemask = 0xff; |
ctx->dsa_write_stencil.stencil[0].writemask = 0xff; |
ctx->dsa_write_depthstencil.depth = ctx->dsa_write_depth.depth; |
ctx->dsa_write_depthstencil.stencil[0] = ctx->dsa_write_stencil.stencil[0]; |
/* rasterizer */ |
ctx->rasterizer.cull_face = PIPE_FACE_NONE; |
ctx->rasterizer.half_pixel_center = 1; |
ctx->rasterizer.bottom_edge_rule = 1; |
ctx->rasterizer.depth_clip = 1; |
/* samplers */ |
ctx->sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; |
ctx->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; |
ctx->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; |
ctx->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; |
ctx->sampler.min_img_filter = 0; /* set later */ |
ctx->sampler.mag_img_filter = 0; /* set later */ |
/* vertex elements state */ |
for (i = 0; i < 2; i++) { |
ctx->velem[i].src_offset = i * 4 * sizeof(float); |
ctx->velem[i].instance_divisor = 0; |
ctx->velem[i].vertex_buffer_index = cso_get_aux_vertex_buffer_slot(cso); |
ctx->velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; |
} |
ctx->vbuf = NULL; |
/* init vertex data that doesn't change */ |
for (i = 0; i < 4; i++) { |
ctx->vertices[i][0][3] = 1.0f; /* w */ |
ctx->vertices[i][1][2] = 0.0f; /* r */ |
ctx->vertices[i][1][3] = 1.0f; /* q */ |
} |
if(pipe->screen->get_param(pipe->screen, PIPE_CAP_NPOT_TEXTURES)) |
ctx->internal_target = PIPE_TEXTURE_2D; |
else |
ctx->internal_target = PIPE_TEXTURE_RECT; |
ctx->has_stencil_export = |
pipe->screen->get_param(pipe->screen, PIPE_CAP_SHADER_STENCIL_EXPORT); |
return ctx; |
} |
/** |
* Destroy a blit context |
*/ |
void |
util_destroy_blit(struct blit_state *ctx) |
{ |
struct pipe_context *pipe = ctx->pipe; |
unsigned i, j; |
if (ctx->vs) |
pipe->delete_vs_state(pipe, ctx->vs); |
for (i = 0; i < Elements(ctx->fs); i++) { |
for (j = 0; j < Elements(ctx->fs[i]); j++) { |
if (ctx->fs[i][j]) |
pipe->delete_fs_state(pipe, ctx->fs[i][j]); |
} |
} |
for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) { |
if (ctx->fs_depthstencil[i]) { |
pipe->delete_fs_state(pipe, ctx->fs_depthstencil[i]); |
} |
if (ctx->fs_depth[i]) { |
pipe->delete_fs_state(pipe, ctx->fs_depth[i]); |
} |
if (ctx->fs_stencil[i]) { |
pipe->delete_fs_state(pipe, ctx->fs_stencil[i]); |
} |
} |
pipe_resource_reference(&ctx->vbuf, NULL); |
FREE(ctx); |
} |
/** |
* Helper function to set the fragment shaders. |
*/ |
static INLINE void |
set_fragment_shader(struct blit_state *ctx, uint writemask, |
enum pipe_texture_target pipe_tex) |
{ |
if (!ctx->fs[pipe_tex][writemask]) { |
unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex, 0); |
ctx->fs[pipe_tex][writemask] = |
util_make_fragment_tex_shader_writemask(ctx->pipe, tgsi_tex, |
TGSI_INTERPOLATE_LINEAR, |
writemask); |
} |
cso_set_fragment_shader_handle(ctx->cso, ctx->fs[pipe_tex][writemask]); |
} |
/** |
* Helper function to set the shader which writes depth and stencil. |
*/ |
static INLINE void |
set_depthstencil_fragment_shader(struct blit_state *ctx, |
enum pipe_texture_target pipe_tex) |
{ |
if (!ctx->fs_depthstencil[pipe_tex]) { |
unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex, 0); |
ctx->fs_depthstencil[pipe_tex] = |
util_make_fragment_tex_shader_writedepthstencil(ctx->pipe, tgsi_tex, |
TGSI_INTERPOLATE_LINEAR); |
} |
cso_set_fragment_shader_handle(ctx->cso, ctx->fs_depthstencil[pipe_tex]); |
} |
/** |
* Helper function to set the shader which writes depth. |
*/ |
static INLINE void |
set_depth_fragment_shader(struct blit_state *ctx, |
enum pipe_texture_target pipe_tex) |
{ |
if (!ctx->fs_depth[pipe_tex]) { |
unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex, 0); |
ctx->fs_depth[pipe_tex] = |
util_make_fragment_tex_shader_writedepth(ctx->pipe, tgsi_tex, |
TGSI_INTERPOLATE_LINEAR); |
} |
cso_set_fragment_shader_handle(ctx->cso, ctx->fs_depth[pipe_tex]); |
} |
/** |
* Helper function to set the shader which writes stencil. |
*/ |
static INLINE void |
set_stencil_fragment_shader(struct blit_state *ctx, |
enum pipe_texture_target pipe_tex) |
{ |
if (!ctx->fs_stencil[pipe_tex]) { |
unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(pipe_tex, 0); |
ctx->fs_stencil[pipe_tex] = |
util_make_fragment_tex_shader_writestencil(ctx->pipe, tgsi_tex, |
TGSI_INTERPOLATE_LINEAR); |
} |
cso_set_fragment_shader_handle(ctx->cso, ctx->fs_stencil[pipe_tex]); |
} |
/** |
* Helper function to set the vertex shader. |
*/ |
static INLINE void |
set_vertex_shader(struct blit_state *ctx) |
{ |
/* vertex shader - still required to provide the linkage between |
* fragment shader input semantics and vertex_element/buffers. |
*/ |
if (!ctx->vs) { |
const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, |
TGSI_SEMANTIC_GENERIC }; |
const uint semantic_indexes[] = { 0, 0 }; |
ctx->vs = util_make_vertex_passthrough_shader(ctx->pipe, 2, |
semantic_names, |
semantic_indexes); |
} |
cso_set_vertex_shader_handle(ctx->cso, ctx->vs); |
} |
/** |
* Get offset of next free slot in vertex buffer for quad vertices. |
*/ |
static unsigned |
get_next_slot( struct blit_state *ctx ) |
{ |
const unsigned max_slots = 4096 / sizeof ctx->vertices; |
if (ctx->vbuf_slot >= max_slots) { |
pipe_resource_reference(&ctx->vbuf, NULL); |
ctx->vbuf_slot = 0; |
} |
if (!ctx->vbuf) { |
ctx->vbuf = pipe_buffer_create(ctx->pipe->screen, |
PIPE_BIND_VERTEX_BUFFER, |
PIPE_USAGE_STREAM, |
max_slots * sizeof ctx->vertices); |
} |
return ctx->vbuf_slot++ * sizeof ctx->vertices; |
} |
/** |
* Setup vertex data for the textured quad we'll draw. |
* Note: y=0=top |
*/ |
static unsigned |
setup_vertex_data_tex(struct blit_state *ctx, |
float x0, float y0, float x1, float y1, |
float s0, float t0, float s1, float t1, |
float z) |
{ |
unsigned offset; |
ctx->vertices[0][0][0] = x0; |
ctx->vertices[0][0][1] = y0; |
ctx->vertices[0][0][2] = z; |
ctx->vertices[0][1][0] = s0; /*s*/ |
ctx->vertices[0][1][1] = t0; /*t*/ |
ctx->vertices[1][0][0] = x1; |
ctx->vertices[1][0][1] = y0; |
ctx->vertices[1][0][2] = z; |
ctx->vertices[1][1][0] = s1; /*s*/ |
ctx->vertices[1][1][1] = t0; /*t*/ |
ctx->vertices[2][0][0] = x1; |
ctx->vertices[2][0][1] = y1; |
ctx->vertices[2][0][2] = z; |
ctx->vertices[2][1][0] = s1; |
ctx->vertices[2][1][1] = t1; |
ctx->vertices[3][0][0] = x0; |
ctx->vertices[3][0][1] = y1; |
ctx->vertices[3][0][2] = z; |
ctx->vertices[3][1][0] = s0; |
ctx->vertices[3][1][1] = t1; |
offset = get_next_slot( ctx ); |
if (ctx->vbuf) { |
pipe_buffer_write_nooverlap(ctx->pipe, ctx->vbuf, |
offset, sizeof(ctx->vertices), ctx->vertices); |
} |
return offset; |
} |
/** |
* \return TRUE if two regions overlap, FALSE otherwise |
*/ |
static boolean |
regions_overlap(int srcX0, int srcY0, |
int srcX1, int srcY1, |
int dstX0, int dstY0, |
int dstX1, int dstY1) |
{ |
if (MAX2(srcX0, srcX1) < MIN2(dstX0, dstX1)) |
return FALSE; /* src completely left of dst */ |
if (MAX2(dstX0, dstX1) < MIN2(srcX0, srcX1)) |
return FALSE; /* dst completely left of src */ |
if (MAX2(srcY0, srcY1) < MIN2(dstY0, dstY1)) |
return FALSE; /* src completely above dst */ |
if (MAX2(dstY0, dstY1) < MIN2(srcY0, srcY1)) |
return FALSE; /* dst completely above src */ |
return TRUE; /* some overlap */ |
} |
/** |
* Can we blit from src format to dest format with a simple copy? |
*/ |
static boolean |
formats_compatible(enum pipe_format src_format, |
enum pipe_format dst_format) |
{ |
if (src_format == dst_format) { |
return TRUE; |
} |
else { |
const struct util_format_description *src_desc = |
util_format_description(src_format); |
const struct util_format_description *dst_desc = |
util_format_description(dst_format); |
return util_is_format_compatible(src_desc, dst_desc); |
} |
} |
/** |
* Copy pixel block from src surface to dst surface. |
* Overlapping regions are acceptable. |
* Flipping and stretching are supported. |
* \param filter one of PIPE_TEX_MIPFILTER_NEAREST/LINEAR |
* \param writemask controls which channels in the dest surface are sourced |
* from the src surface. Disabled channels are sourced |
* from (0,0,0,1). |
*/ |
void |
util_blit_pixels(struct blit_state *ctx, |
struct pipe_resource *src_tex, |
unsigned src_level, |
int srcX0, int srcY0, |
int srcX1, int srcY1, |
int srcZ0, |
struct pipe_surface *dst, |
int dstX0, int dstY0, |
int dstX1, int dstY1, |
float z, uint filter, |
uint writemask, uint zs_writemask) |
{ |
struct pipe_context *pipe = ctx->pipe; |
struct pipe_screen *screen = pipe->screen; |
enum pipe_format src_format, dst_format; |
struct pipe_sampler_view *sampler_view = NULL; |
struct pipe_sampler_view sv_templ; |
struct pipe_surface *dst_surface; |
struct pipe_framebuffer_state fb; |
const int srcW = abs(srcX1 - srcX0); |
const int srcH = abs(srcY1 - srcY0); |
unsigned offset; |
boolean overlap; |
float s0, t0, s1, t1; |
boolean normalized; |
boolean is_stencil, is_depth, blit_depth, blit_stencil; |
const struct util_format_description *src_desc = |
util_format_description(src_tex->format); |
assert(filter == PIPE_TEX_MIPFILTER_NEAREST || |
filter == PIPE_TEX_MIPFILTER_LINEAR); |
assert(src_level <= src_tex->last_level); |
/* do the regions overlap? */ |
overlap = src_tex == dst->texture && |
dst->u.tex.level == src_level && |
dst->u.tex.first_layer == srcZ0 && |
regions_overlap(srcX0, srcY0, srcX1, srcY1, |
dstX0, dstY0, dstX1, dstY1); |
src_format = util_format_linear(src_tex->format); |
dst_format = util_format_linear(dst->texture->format); |
/* See whether we will blit depth or stencil. */ |
is_depth = util_format_has_depth(src_desc); |
is_stencil = util_format_has_stencil(src_desc); |
blit_depth = is_depth && (zs_writemask & BLIT_WRITEMASK_Z); |
blit_stencil = is_stencil && (zs_writemask & BLIT_WRITEMASK_STENCIL); |
assert((writemask && !zs_writemask && !is_depth && !is_stencil) || |
(!writemask && (blit_depth || blit_stencil))); |
/* |
* Check for simple case: no format conversion, no flipping, no stretching, |
* no overlapping, same number of samples. |
* Filter mode should not matter since there's no stretching. |
*/ |
if (formats_compatible(src_format, dst_format) && |
src_tex->nr_samples == dst->texture->nr_samples && |
is_stencil == blit_stencil && |
is_depth == blit_depth && |
srcX0 < srcX1 && |
dstX0 < dstX1 && |
srcY0 < srcY1 && |
dstY0 < dstY1 && |
(dstX1 - dstX0) == (srcX1 - srcX0) && |
(dstY1 - dstY0) == (srcY1 - srcY0) && |
!overlap) { |
struct pipe_box src_box; |
src_box.x = srcX0; |
src_box.y = srcY0; |
src_box.z = srcZ0; |
src_box.width = srcW; |
src_box.height = srcH; |
src_box.depth = 1; |
pipe->resource_copy_region(pipe, |
dst->texture, dst->u.tex.level, |
dstX0, dstY0, dst->u.tex.first_layer,/* dest */ |
src_tex, src_level, |
&src_box); |
return; |
} |
/* XXX Reading multisample textures is unimplemented. */ |
assert(src_tex->nr_samples <= 1); |
if (src_tex->nr_samples > 1) { |
return; |
} |
/* It's a mistake to call this function with a stencil format and |
* without shader stencil export. We don't do software fallbacks here. |
* Ignore stencil and only copy depth. |
*/ |
if (blit_stencil && !ctx->has_stencil_export) { |
blit_stencil = FALSE; |
if (!blit_depth) |
return; |
} |
if (dst_format == dst->format) { |
dst_surface = dst; |
} else { |
struct pipe_surface templ = *dst; |
templ.format = dst_format; |
dst_surface = pipe->create_surface(pipe, dst->texture, &templ); |
} |
/* Create a temporary texture when src and dest alias. |
*/ |
if (src_tex == dst_surface->texture && |
dst_surface->u.tex.level == src_level && |
dst_surface->u.tex.first_layer == srcZ0) { |
/* Make a temporary texture which contains a copy of the source pixels. |
* Then we'll sample from the temporary texture. |
*/ |
struct pipe_resource texTemp; |
struct pipe_resource *tex; |
struct pipe_sampler_view sv_templ; |
struct pipe_box src_box; |
const int srcLeft = MIN2(srcX0, srcX1); |
const int srcTop = MIN2(srcY0, srcY1); |
if (srcLeft != srcX0) { |
/* left-right flip */ |
int tmp = dstX0; |
dstX0 = dstX1; |
dstX1 = tmp; |
} |
if (srcTop != srcY0) { |
/* up-down flip */ |
int tmp = dstY0; |
dstY0 = dstY1; |
dstY1 = tmp; |
} |
/* create temp texture */ |
memset(&texTemp, 0, sizeof(texTemp)); |
texTemp.target = ctx->internal_target; |
texTemp.format = src_format; |
texTemp.last_level = 0; |
texTemp.width0 = srcW; |
texTemp.height0 = srcH; |
texTemp.depth0 = 1; |
texTemp.array_size = 1; |
texTemp.bind = PIPE_BIND_SAMPLER_VIEW; |
tex = screen->resource_create(screen, &texTemp); |
if (!tex) |
return; |
src_box.x = srcLeft; |
src_box.y = srcTop; |
src_box.z = srcZ0; |
src_box.width = srcW; |
src_box.height = srcH; |
src_box.depth = 1; |
/* load temp texture */ |
pipe->resource_copy_region(pipe, |
tex, 0, 0, 0, 0, /* dest */ |
src_tex, src_level, &src_box); |
normalized = tex->target != PIPE_TEXTURE_RECT; |
if(normalized) { |
s0 = 0.0f; |
s1 = 1.0f; |
t0 = 0.0f; |
t1 = 1.0f; |
} |
else { |
s0 = 0.0f; |
s1 = (float) srcW; |
t0 = 0.0f; |
t1 = (float) srcH; |
} |
u_sampler_view_default_template(&sv_templ, tex, tex->format); |
if (!blit_depth && blit_stencil) { |
/* set a stencil-only format, e.g. Z24S8 --> X24S8 */ |
sv_templ.format = util_format_stencil_only(tex->format); |
assert(sv_templ.format != PIPE_FORMAT_NONE); |
} |
sampler_view = pipe->create_sampler_view(pipe, tex, &sv_templ); |
if (!sampler_view) { |
pipe_resource_reference(&tex, NULL); |
return; |
} |
pipe_resource_reference(&tex, NULL); |
} |
else { |
/* Directly sample from the source resource/texture */ |
u_sampler_view_default_template(&sv_templ, src_tex, src_format); |
if (!blit_depth && blit_stencil) { |
/* set a stencil-only format, e.g. Z24S8 --> X24S8 */ |
sv_templ.format = util_format_stencil_only(src_format); |
assert(sv_templ.format != PIPE_FORMAT_NONE); |
} |
sampler_view = pipe->create_sampler_view(pipe, src_tex, &sv_templ); |
if (!sampler_view) { |
return; |
} |
s0 = (float) srcX0; |
s1 = (float) srcX1; |
t0 = (float) srcY0; |
t1 = (float) srcY1; |
normalized = sampler_view->texture->target != PIPE_TEXTURE_RECT; |
if(normalized) |
{ |
s0 /= (float)(u_minify(sampler_view->texture->width0, src_level)); |
s1 /= (float)(u_minify(sampler_view->texture->width0, src_level)); |
t0 /= (float)(u_minify(sampler_view->texture->height0, src_level)); |
t1 /= (float)(u_minify(sampler_view->texture->height0, src_level)); |
} |
} |
assert(screen->is_format_supported(screen, sampler_view->format, |
ctx->internal_target, sampler_view->texture->nr_samples, |
PIPE_BIND_SAMPLER_VIEW)); |
assert(screen->is_format_supported(screen, dst_format, ctx->internal_target, |
dst_surface->texture->nr_samples, |
is_depth || is_stencil ? PIPE_BIND_DEPTH_STENCIL : |
PIPE_BIND_RENDER_TARGET)); |
/* save state (restored below) */ |
cso_save_blend(ctx->cso); |
cso_save_depth_stencil_alpha(ctx->cso); |
cso_save_rasterizer(ctx->cso); |
cso_save_sample_mask(ctx->cso); |
cso_save_samplers(ctx->cso, PIPE_SHADER_FRAGMENT); |
cso_save_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT); |
cso_save_stream_outputs(ctx->cso); |
cso_save_viewport(ctx->cso); |
cso_save_framebuffer(ctx->cso); |
cso_save_fragment_shader(ctx->cso); |
cso_save_vertex_shader(ctx->cso); |
cso_save_geometry_shader(ctx->cso); |
cso_save_vertex_elements(ctx->cso); |
cso_save_aux_vertex_buffer_slot(ctx->cso); |
cso_save_render_condition(ctx->cso); |
/* set misc state we care about */ |
if (writemask) |
cso_set_blend(ctx->cso, &ctx->blend_write_color); |
else |
cso_set_blend(ctx->cso, &ctx->blend_keep_color); |
cso_set_sample_mask(ctx->cso, ~0); |
cso_set_rasterizer(ctx->cso, &ctx->rasterizer); |
cso_set_vertex_elements(ctx->cso, 2, ctx->velem); |
cso_set_stream_outputs(ctx->cso, 0, NULL, 0); |
cso_set_render_condition(ctx->cso, NULL, FALSE, 0); |
/* default sampler state */ |
ctx->sampler.normalized_coords = normalized; |
ctx->sampler.min_img_filter = filter; |
ctx->sampler.mag_img_filter = filter; |
ctx->sampler.min_lod = (float) src_level; |
ctx->sampler.max_lod = (float) src_level; |
/* Depth stencil state, fragment shader and sampler setup depending on what |
* we blit. |
*/ |
if (blit_depth && blit_stencil) { |
cso_single_sampler(ctx->cso, PIPE_SHADER_FRAGMENT, 0, &ctx->sampler); |
/* don't filter stencil */ |
ctx->sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; |
ctx->sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; |
cso_single_sampler(ctx->cso, PIPE_SHADER_FRAGMENT, 1, &ctx->sampler); |
cso_set_depth_stencil_alpha(ctx->cso, &ctx->dsa_write_depthstencil); |
set_depthstencil_fragment_shader(ctx, sampler_view->texture->target); |
} |
else if (blit_depth) { |
cso_single_sampler(ctx->cso, PIPE_SHADER_FRAGMENT, 0, &ctx->sampler); |
cso_set_depth_stencil_alpha(ctx->cso, &ctx->dsa_write_depth); |
set_depth_fragment_shader(ctx, sampler_view->texture->target); |
} |
else if (blit_stencil) { |
/* don't filter stencil */ |
ctx->sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST; |
ctx->sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST; |
cso_single_sampler(ctx->cso, PIPE_SHADER_FRAGMENT, 0, &ctx->sampler); |
cso_set_depth_stencil_alpha(ctx->cso, &ctx->dsa_write_stencil); |
set_stencil_fragment_shader(ctx, sampler_view->texture->target); |
} |
else { /* color */ |
cso_single_sampler(ctx->cso, PIPE_SHADER_FRAGMENT, 0, &ctx->sampler); |
cso_set_depth_stencil_alpha(ctx->cso, &ctx->dsa_keep_depthstencil); |
set_fragment_shader(ctx, writemask, sampler_view->texture->target); |
} |
cso_single_sampler_done(ctx->cso, PIPE_SHADER_FRAGMENT); |
/* textures */ |
if (blit_depth && blit_stencil) { |
/* Setup two samplers, one for depth and the other one for stencil. */ |
struct pipe_sampler_view templ; |
struct pipe_sampler_view *views[2]; |
templ = *sampler_view; |
templ.format = util_format_stencil_only(templ.format); |
assert(templ.format != PIPE_FORMAT_NONE); |
views[0] = sampler_view; |
views[1] = pipe->create_sampler_view(pipe, views[0]->texture, &templ); |
cso_set_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT, 2, views); |
pipe_sampler_view_reference(&views[1], NULL); |
} |
else { |
cso_set_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT, 1, &sampler_view); |
} |
/* viewport */ |
ctx->viewport.scale[0] = 0.5f * dst_surface->width; |
ctx->viewport.scale[1] = 0.5f * dst_surface->height; |
ctx->viewport.scale[2] = 0.5f; |
ctx->viewport.scale[3] = 1.0f; |
ctx->viewport.translate[0] = 0.5f * dst_surface->width; |
ctx->viewport.translate[1] = 0.5f * dst_surface->height; |
ctx->viewport.translate[2] = 0.5f; |
ctx->viewport.translate[3] = 0.0f; |
cso_set_viewport(ctx->cso, &ctx->viewport); |
set_vertex_shader(ctx); |
cso_set_geometry_shader_handle(ctx->cso, NULL); |
/* drawing dest */ |
memset(&fb, 0, sizeof(fb)); |
fb.width = dst_surface->width; |
fb.height = dst_surface->height; |
if (blit_depth || blit_stencil) { |
fb.zsbuf = dst_surface; |
} else { |
fb.nr_cbufs = 1; |
fb.cbufs[0] = dst_surface; |
} |
cso_set_framebuffer(ctx->cso, &fb); |
/* draw quad */ |
offset = setup_vertex_data_tex(ctx, |
(float) dstX0 / dst_surface->width * 2.0f - 1.0f, |
(float) dstY0 / dst_surface->height * 2.0f - 1.0f, |
(float) dstX1 / dst_surface->width * 2.0f - 1.0f, |
(float) dstY1 / dst_surface->height * 2.0f - 1.0f, |
s0, t0, |
s1, t1, |
z); |
if (ctx->vbuf) { |
util_draw_vertex_buffer(ctx->pipe, ctx->cso, ctx->vbuf, |
cso_get_aux_vertex_buffer_slot(ctx->cso), |
offset, |
PIPE_PRIM_TRIANGLE_FAN, |
4, /* verts */ |
2); /* attribs/vert */ |
} |
/* restore state we changed */ |
cso_restore_blend(ctx->cso); |
cso_restore_depth_stencil_alpha(ctx->cso); |
cso_restore_rasterizer(ctx->cso); |
cso_restore_sample_mask(ctx->cso); |
cso_restore_samplers(ctx->cso, PIPE_SHADER_FRAGMENT); |
cso_restore_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT); |
cso_restore_viewport(ctx->cso); |
cso_restore_framebuffer(ctx->cso); |
cso_restore_fragment_shader(ctx->cso); |
cso_restore_vertex_shader(ctx->cso); |
cso_restore_geometry_shader(ctx->cso); |
cso_restore_vertex_elements(ctx->cso); |
cso_restore_aux_vertex_buffer_slot(ctx->cso); |
cso_restore_stream_outputs(ctx->cso); |
cso_restore_render_condition(ctx->cso); |
pipe_sampler_view_reference(&sampler_view, NULL); |
if (dst_surface != dst) |
pipe_surface_reference(&dst_surface, NULL); |
} |
/** |
* Copy pixel block from src texture to dst surface. |
* The sampler view's first_level field indicates the source |
* mipmap level to use. |
* XXX need some control over blitting Z and/or stencil. |
*/ |
void |
util_blit_pixels_tex(struct blit_state *ctx, |
struct pipe_sampler_view *src_sampler_view, |
int srcX0, int srcY0, |
int srcX1, int srcY1, |
struct pipe_surface *dst, |
int dstX0, int dstY0, |
int dstX1, int dstY1, |
float z, uint filter) |
{ |
boolean normalized = src_sampler_view->texture->target != PIPE_TEXTURE_RECT; |
struct pipe_framebuffer_state fb; |
float s0, t0, s1, t1; |
unsigned offset; |
struct pipe_resource *tex = src_sampler_view->texture; |
assert(filter == PIPE_TEX_MIPFILTER_NEAREST || |
filter == PIPE_TEX_MIPFILTER_LINEAR); |
assert(tex); |
assert(tex->width0 != 0); |
assert(tex->height0 != 0); |
s0 = (float) srcX0; |
s1 = (float) srcX1; |
t0 = (float) srcY0; |
t1 = (float) srcY1; |
if(normalized) |
{ |
/* normalize according to the mipmap level's size */ |
int level = src_sampler_view->u.tex.first_level; |
float w = (float) u_minify(tex->width0, level); |
float h = (float) u_minify(tex->height0, level); |
s0 /= w; |
s1 /= w; |
t0 /= h; |
t1 /= h; |
} |
assert(ctx->pipe->screen->is_format_supported(ctx->pipe->screen, dst->format, |
PIPE_TEXTURE_2D, |
dst->texture->nr_samples, |
PIPE_BIND_RENDER_TARGET)); |
/* save state (restored below) */ |
cso_save_blend(ctx->cso); |
cso_save_depth_stencil_alpha(ctx->cso); |
cso_save_rasterizer(ctx->cso); |
cso_save_sample_mask(ctx->cso); |
cso_save_samplers(ctx->cso, PIPE_SHADER_FRAGMENT); |
cso_save_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT); |
cso_save_stream_outputs(ctx->cso); |
cso_save_viewport(ctx->cso); |
cso_save_framebuffer(ctx->cso); |
cso_save_fragment_shader(ctx->cso); |
cso_save_vertex_shader(ctx->cso); |
cso_save_geometry_shader(ctx->cso); |
cso_save_vertex_elements(ctx->cso); |
cso_save_aux_vertex_buffer_slot(ctx->cso); |
/* set misc state we care about */ |
cso_set_blend(ctx->cso, &ctx->blend_write_color); |
cso_set_depth_stencil_alpha(ctx->cso, &ctx->dsa_keep_depthstencil); |
cso_set_sample_mask(ctx->cso, ~0); |
cso_set_rasterizer(ctx->cso, &ctx->rasterizer); |
cso_set_vertex_elements(ctx->cso, 2, ctx->velem); |
cso_set_stream_outputs(ctx->cso, 0, NULL, 0); |
/* sampler */ |
ctx->sampler.normalized_coords = normalized; |
ctx->sampler.min_img_filter = filter; |
ctx->sampler.mag_img_filter = filter; |
cso_single_sampler(ctx->cso, PIPE_SHADER_FRAGMENT, 0, &ctx->sampler); |
cso_single_sampler_done(ctx->cso, PIPE_SHADER_FRAGMENT); |
/* viewport */ |
ctx->viewport.scale[0] = 0.5f * dst->width; |
ctx->viewport.scale[1] = 0.5f * dst->height; |
ctx->viewport.scale[2] = 0.5f; |
ctx->viewport.scale[3] = 1.0f; |
ctx->viewport.translate[0] = 0.5f * dst->width; |
ctx->viewport.translate[1] = 0.5f * dst->height; |
ctx->viewport.translate[2] = 0.5f; |
ctx->viewport.translate[3] = 0.0f; |
cso_set_viewport(ctx->cso, &ctx->viewport); |
/* texture */ |
cso_set_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT, 1, &src_sampler_view); |
/* shaders */ |
set_fragment_shader(ctx, TGSI_WRITEMASK_XYZW, |
src_sampler_view->texture->target); |
set_vertex_shader(ctx); |
cso_set_geometry_shader_handle(ctx->cso, NULL); |
/* drawing dest */ |
memset(&fb, 0, sizeof(fb)); |
fb.width = dst->width; |
fb.height = dst->height; |
fb.nr_cbufs = 1; |
fb.cbufs[0] = dst; |
cso_set_framebuffer(ctx->cso, &fb); |
/* draw quad */ |
offset = setup_vertex_data_tex(ctx, |
(float) dstX0 / dst->width * 2.0f - 1.0f, |
(float) dstY0 / dst->height * 2.0f - 1.0f, |
(float) dstX1 / dst->width * 2.0f - 1.0f, |
(float) dstY1 / dst->height * 2.0f - 1.0f, |
s0, t0, s1, t1, |
z); |
util_draw_vertex_buffer(ctx->pipe, ctx->cso, ctx->vbuf, |
cso_get_aux_vertex_buffer_slot(ctx->cso), |
offset, |
PIPE_PRIM_TRIANGLE_FAN, |
4, /* verts */ |
2); /* attribs/vert */ |
/* restore state we changed */ |
cso_restore_blend(ctx->cso); |
cso_restore_depth_stencil_alpha(ctx->cso); |
cso_restore_rasterizer(ctx->cso); |
cso_restore_sample_mask(ctx->cso); |
cso_restore_samplers(ctx->cso, PIPE_SHADER_FRAGMENT); |
cso_restore_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT); |
cso_restore_viewport(ctx->cso); |
cso_restore_framebuffer(ctx->cso); |
cso_restore_fragment_shader(ctx->cso); |
cso_restore_vertex_shader(ctx->cso); |
cso_restore_geometry_shader(ctx->cso); |
cso_restore_vertex_elements(ctx->cso); |
cso_restore_aux_vertex_buffer_slot(ctx->cso); |
cso_restore_stream_outputs(ctx->cso); |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_blit.h |
---|
0,0 → 1,85 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* 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 TUNGSTEN GRAPHICS 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_BLIT_H |
#define U_BLIT_H |
#include "pipe/p_compiler.h" |
/* for TGSI_WRITEMASK_* specification in util_blit_pixels */ |
#include "pipe/p_shader_tokens.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
struct cso_context; |
struct pipe_context; |
struct pipe_resource; |
struct pipe_sampler_view; |
struct pipe_surface; |
#define BLIT_WRITEMASK_Z 1 |
#define BLIT_WRITEMASK_STENCIL 2 |
extern struct blit_state * |
util_create_blit(struct pipe_context *pipe, struct cso_context *cso); |
extern void |
util_destroy_blit(struct blit_state *ctx); |
extern void |
util_blit_pixels(struct blit_state *ctx, |
struct pipe_resource *src_tex, |
unsigned src_level, |
int srcX0, int srcY0, |
int srcX1, int srcY1, |
int srcZ0, |
struct pipe_surface *dst, |
int dstX0, int dstY0, |
int dstX1, int dstY1, |
float z, uint filter, |
uint writemask, uint zs_writemask); |
extern void |
util_blit_pixels_tex(struct blit_state *ctx, |
struct pipe_sampler_view *src_sampler_view, |
int srcX0, int srcY0, |
int srcX1, int srcY1, |
struct pipe_surface *dst, |
int dstX0, int dstY0, |
int dstX1, int dstY1, |
float z, uint filter); |
#ifdef __cplusplus |
} |
#endif |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_blitter.c |
---|
0,0 → 1,1877 |
/************************************************************************** |
* |
* Copyright 2009 Marek Olšák <maraeo@gmail.com> |
* |
* 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 TUNGSTEN GRAPHICS 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. |
* |
**************************************************************************/ |
/** |
* @file |
* Blitter utility to facilitate acceleration of the clear, clear_render_target, |
* clear_depth_stencil, resource_copy_region, and blit functions. |
* |
* @author Marek Olšák |
*/ |
#include "pipe/p_context.h" |
#include "pipe/p_defines.h" |
#include "util/u_inlines.h" |
#include "pipe/p_shader_tokens.h" |
#include "pipe/p_state.h" |
#include "util/u_format.h" |
#include "util/u_memory.h" |
#include "util/u_math.h" |
#include "util/u_blitter.h" |
#include "util/u_draw_quad.h" |
#include "util/u_sampler.h" |
#include "util/u_simple_shaders.h" |
#include "util/u_surface.h" |
#include "util/u_texture.h" |
#include "util/u_upload_mgr.h" |
#define INVALID_PTR ((void*)~0) |
struct blitter_context_priv |
{ |
struct blitter_context base; |
struct u_upload_mgr *upload; |
float vertices[4][2][4]; /**< {pos, color} or {pos, texcoord} */ |
/* Templates for various state objects. */ |
/* Constant state objects. */ |
/* Vertex shaders. */ |
void *vs; /**< Vertex shader which passes {pos, generic} to the output.*/ |
void *vs_pos_only; /**< Vertex shader which passes pos to the output.*/ |
/* Fragment shaders. */ |
void *fs_empty; |
void *fs_write_one_cbuf; |
void *fs_write_all_cbufs; |
/* FS which outputs a color from a texture, |
where the index is PIPE_TEXTURE_* to be sampled. */ |
void *fs_texfetch_col[PIPE_MAX_TEXTURE_TYPES]; |
/* FS which outputs a depth from a texture, |
where the index is PIPE_TEXTURE_* to be sampled. */ |
void *fs_texfetch_depth[PIPE_MAX_TEXTURE_TYPES]; |
void *fs_texfetch_depthstencil[PIPE_MAX_TEXTURE_TYPES]; |
void *fs_texfetch_stencil[PIPE_MAX_TEXTURE_TYPES]; |
/* FS which outputs one sample from a multisample texture. */ |
void *fs_texfetch_col_msaa[PIPE_MAX_TEXTURE_TYPES]; |
void *fs_texfetch_depth_msaa[PIPE_MAX_TEXTURE_TYPES]; |
void *fs_texfetch_depthstencil_msaa[PIPE_MAX_TEXTURE_TYPES]; |
void *fs_texfetch_stencil_msaa[PIPE_MAX_TEXTURE_TYPES]; |
/* Blend state. */ |
void *blend[PIPE_MASK_RGBA+1]; /**< blend state with writemask */ |
/* Depth stencil alpha state. */ |
void *dsa_write_depth_stencil; |
void *dsa_write_depth_keep_stencil; |
void *dsa_keep_depth_stencil; |
void *dsa_keep_depth_write_stencil; |
/* Vertex elements states. */ |
void *velem_state; |
void *velem_state_readbuf[4]; /**< X, XY, XYZ, XYZW */ |
/* Sampler state. */ |
void *sampler_state; |
void *sampler_state_linear; |
void *sampler_state_rect; |
void *sampler_state_rect_linear; |
/* Rasterizer state. */ |
void *rs_state, *rs_state_scissor, *rs_discard_state; |
/* Viewport state. */ |
struct pipe_viewport_state viewport; |
/* Destination surface dimensions. */ |
unsigned dst_width; |
unsigned dst_height; |
boolean has_geometry_shader; |
boolean has_stream_out; |
boolean has_stencil_export; |
boolean has_texture_multisample; |
/* The Draw module overrides these functions. |
* Always create the blitter before Draw. */ |
void (*bind_fs_state)(struct pipe_context *, void *); |
void (*delete_fs_state)(struct pipe_context *, void *); |
}; |
static struct pipe_surface * |
util_blitter_get_next_surface_layer(struct pipe_context *pipe, |
struct pipe_surface *surf); |
struct blitter_context *util_blitter_create(struct pipe_context *pipe) |
{ |
struct blitter_context_priv *ctx; |
struct pipe_blend_state blend; |
struct pipe_depth_stencil_alpha_state dsa; |
struct pipe_rasterizer_state rs_state; |
struct pipe_sampler_state sampler_state; |
struct pipe_vertex_element velem[2]; |
unsigned i; |
ctx = CALLOC_STRUCT(blitter_context_priv); |
if (!ctx) |
return NULL; |
ctx->base.pipe = pipe; |
ctx->base.draw_rectangle = util_blitter_draw_rectangle; |
ctx->base.get_next_surface_layer = util_blitter_get_next_surface_layer; |
ctx->bind_fs_state = pipe->bind_fs_state; |
ctx->delete_fs_state = pipe->delete_fs_state; |
/* init state objects for them to be considered invalid */ |
ctx->base.saved_blend_state = INVALID_PTR; |
ctx->base.saved_dsa_state = INVALID_PTR; |
ctx->base.saved_rs_state = INVALID_PTR; |
ctx->base.saved_fs = INVALID_PTR; |
ctx->base.saved_vs = INVALID_PTR; |
ctx->base.saved_gs = INVALID_PTR; |
ctx->base.saved_velem_state = INVALID_PTR; |
ctx->base.saved_fb_state.nr_cbufs = ~0; |
ctx->base.saved_num_sampler_views = ~0; |
ctx->base.saved_num_sampler_states = ~0; |
ctx->base.saved_num_so_targets = ~0; |
ctx->has_geometry_shader = |
pipe->screen->get_shader_param(pipe->screen, PIPE_SHADER_GEOMETRY, |
PIPE_SHADER_CAP_MAX_INSTRUCTIONS) > 0; |
ctx->has_stream_out = |
pipe->screen->get_param(pipe->screen, |
PIPE_CAP_MAX_STREAM_OUTPUT_BUFFERS) != 0; |
ctx->has_stencil_export = |
pipe->screen->get_param(pipe->screen, |
PIPE_CAP_SHADER_STENCIL_EXPORT); |
ctx->has_texture_multisample = |
pipe->screen->get_param(pipe->screen, PIPE_CAP_TEXTURE_MULTISAMPLE); |
/* blend state objects */ |
memset(&blend, 0, sizeof(blend)); |
for (i = 0; i <= PIPE_MASK_RGBA; i++) { |
blend.rt[0].colormask = i; |
ctx->blend[i] = pipe->create_blend_state(pipe, &blend); |
} |
/* depth stencil alpha state objects */ |
memset(&dsa, 0, sizeof(dsa)); |
ctx->dsa_keep_depth_stencil = |
pipe->create_depth_stencil_alpha_state(pipe, &dsa); |
dsa.depth.enabled = 1; |
dsa.depth.writemask = 1; |
dsa.depth.func = PIPE_FUNC_ALWAYS; |
ctx->dsa_write_depth_keep_stencil = |
pipe->create_depth_stencil_alpha_state(pipe, &dsa); |
dsa.stencil[0].enabled = 1; |
dsa.stencil[0].func = PIPE_FUNC_ALWAYS; |
dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE; |
dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE; |
dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE; |
dsa.stencil[0].valuemask = 0xff; |
dsa.stencil[0].writemask = 0xff; |
ctx->dsa_write_depth_stencil = |
pipe->create_depth_stencil_alpha_state(pipe, &dsa); |
dsa.depth.enabled = 0; |
dsa.depth.writemask = 0; |
ctx->dsa_keep_depth_write_stencil = |
pipe->create_depth_stencil_alpha_state(pipe, &dsa); |
/* sampler state */ |
memset(&sampler_state, 0, sizeof(sampler_state)); |
sampler_state.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; |
sampler_state.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; |
sampler_state.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; |
sampler_state.normalized_coords = 1; |
ctx->sampler_state = pipe->create_sampler_state(pipe, &sampler_state); |
sampler_state.normalized_coords = 0; |
ctx->sampler_state_rect = pipe->create_sampler_state(pipe, &sampler_state); |
sampler_state.min_img_filter = PIPE_TEX_FILTER_LINEAR; |
sampler_state.mag_img_filter = PIPE_TEX_FILTER_LINEAR; |
sampler_state.normalized_coords = 1; |
ctx->sampler_state_linear = pipe->create_sampler_state(pipe, &sampler_state); |
sampler_state.normalized_coords = 0; |
ctx->sampler_state_rect_linear = pipe->create_sampler_state(pipe, &sampler_state); |
/* rasterizer state */ |
memset(&rs_state, 0, sizeof(rs_state)); |
rs_state.cull_face = PIPE_FACE_NONE; |
rs_state.half_pixel_center = 1; |
rs_state.bottom_edge_rule = 1; |
rs_state.flatshade = 1; |
rs_state.depth_clip = 1; |
ctx->rs_state = pipe->create_rasterizer_state(pipe, &rs_state); |
rs_state.scissor = 1; |
ctx->rs_state_scissor = pipe->create_rasterizer_state(pipe, &rs_state); |
if (ctx->has_stream_out) { |
rs_state.scissor = 0; |
rs_state.rasterizer_discard = 1; |
ctx->rs_discard_state = pipe->create_rasterizer_state(pipe, &rs_state); |
} |
ctx->base.vb_slot = 0; /* 0 for now */ |
/* vertex elements states */ |
memset(&velem[0], 0, sizeof(velem[0]) * 2); |
for (i = 0; i < 2; i++) { |
velem[i].src_offset = i * 4 * sizeof(float); |
velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; |
velem[i].vertex_buffer_index = ctx->base.vb_slot; |
} |
ctx->velem_state = pipe->create_vertex_elements_state(pipe, 2, &velem[0]); |
if (ctx->has_stream_out) { |
static enum pipe_format formats[4] = { |
PIPE_FORMAT_R32_UINT, |
PIPE_FORMAT_R32G32_UINT, |
PIPE_FORMAT_R32G32B32_UINT, |
PIPE_FORMAT_R32G32B32A32_UINT |
}; |
for (i = 0; i < 4; i++) { |
velem[0].src_format = formats[i]; |
velem[0].vertex_buffer_index = ctx->base.vb_slot; |
ctx->velem_state_readbuf[i] = |
pipe->create_vertex_elements_state(pipe, 1, &velem[0]); |
} |
} |
/* Fragment shaders are created on-demand, except these. |
* The interpolation must be constant for integer texture clearing to work. |
*/ |
ctx->fs_empty = util_make_empty_fragment_shader(pipe); |
ctx->fs_write_one_cbuf = |
util_make_fragment_passthrough_shader(pipe, TGSI_SEMANTIC_GENERIC, |
TGSI_INTERPOLATE_CONSTANT, FALSE); |
ctx->fs_write_all_cbufs = |
util_make_fragment_passthrough_shader(pipe, TGSI_SEMANTIC_GENERIC, |
TGSI_INTERPOLATE_CONSTANT, TRUE); |
/* vertex shaders */ |
{ |
const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, |
TGSI_SEMANTIC_GENERIC }; |
const uint semantic_indices[] = { 0, 0 }; |
ctx->vs = |
util_make_vertex_passthrough_shader(pipe, 2, semantic_names, |
semantic_indices); |
} |
if (ctx->has_stream_out) { |
struct pipe_stream_output_info so; |
const uint semantic_names[] = { TGSI_SEMANTIC_POSITION }; |
const uint semantic_indices[] = { 0 }; |
memset(&so, 0, sizeof(so)); |
so.num_outputs = 1; |
so.output[0].num_components = 1; |
so.stride[0] = 1; |
ctx->vs_pos_only = |
util_make_vertex_passthrough_shader_with_so(pipe, 1, semantic_names, |
semantic_indices, &so); |
} |
/* set invariant vertex coordinates */ |
for (i = 0; i < 4; i++) |
ctx->vertices[i][0][3] = 1; /*v.w*/ |
ctx->upload = u_upload_create(pipe, 65536, 4, PIPE_BIND_VERTEX_BUFFER); |
return &ctx->base; |
} |
void util_blitter_destroy(struct blitter_context *blitter) |
{ |
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; |
struct pipe_context *pipe = blitter->pipe; |
int i; |
for (i = 0; i <= PIPE_MASK_RGBA; i++) { |
pipe->delete_blend_state(pipe, ctx->blend[i]); |
} |
pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); |
pipe->delete_depth_stencil_alpha_state(pipe, |
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_rasterizer_state(pipe, ctx->rs_state); |
pipe->delete_rasterizer_state(pipe, ctx->rs_state_scissor); |
if (ctx->rs_discard_state) |
pipe->delete_rasterizer_state(pipe, ctx->rs_discard_state); |
pipe->delete_vs_state(pipe, ctx->vs); |
if (ctx->vs_pos_only) |
pipe->delete_vs_state(pipe, ctx->vs_pos_only); |
pipe->delete_vertex_elements_state(pipe, ctx->velem_state); |
for (i = 0; i < 4; i++) { |
if (ctx->velem_state_readbuf[i]) { |
pipe->delete_vertex_elements_state(pipe, ctx->velem_state_readbuf[i]); |
} |
} |
for (i = 0; i < PIPE_MAX_TEXTURE_TYPES; i++) { |
if (ctx->fs_texfetch_col[i]) |
ctx->delete_fs_state(pipe, ctx->fs_texfetch_col[i]); |
if (ctx->fs_texfetch_depth[i]) |
ctx->delete_fs_state(pipe, ctx->fs_texfetch_depth[i]); |
if (ctx->fs_texfetch_depthstencil[i]) |
ctx->delete_fs_state(pipe, ctx->fs_texfetch_depthstencil[i]); |
if (ctx->fs_texfetch_stencil[i]) |
ctx->delete_fs_state(pipe, ctx->fs_texfetch_stencil[i]); |
} |
ctx->delete_fs_state(pipe, ctx->fs_empty); |
ctx->delete_fs_state(pipe, ctx->fs_write_one_cbuf); |
ctx->delete_fs_state(pipe, ctx->fs_write_all_cbufs); |
pipe->delete_sampler_state(pipe, ctx->sampler_state_rect_linear); |
pipe->delete_sampler_state(pipe, ctx->sampler_state_rect); |
pipe->delete_sampler_state(pipe, ctx->sampler_state_linear); |
pipe->delete_sampler_state(pipe, ctx->sampler_state); |
u_upload_destroy(ctx->upload); |
FREE(ctx); |
} |
void util_blitter_set_texture_multisample(struct blitter_context *blitter, |
boolean supported) |
{ |
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; |
ctx->has_texture_multisample = supported; |
} |
static void blitter_set_running_flag(struct blitter_context_priv *ctx) |
{ |
if (ctx->base.running) { |
_debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n", |
__LINE__); |
} |
ctx->base.running = TRUE; |
} |
static void blitter_unset_running_flag(struct blitter_context_priv *ctx) |
{ |
if (!ctx->base.running) { |
_debug_printf("u_blitter:%i: Caught recursion. This is a driver bug.\n", |
__LINE__); |
} |
ctx->base.running = FALSE; |
} |
static void blitter_check_saved_vertex_states(struct blitter_context_priv *ctx) |
{ |
assert(ctx->base.saved_velem_state != INVALID_PTR); |
assert(ctx->base.saved_vs != INVALID_PTR); |
assert(!ctx->has_geometry_shader || ctx->base.saved_gs != INVALID_PTR); |
assert(!ctx->has_stream_out || ctx->base.saved_num_so_targets != ~0); |
assert(ctx->base.saved_rs_state != INVALID_PTR); |
} |
static void blitter_restore_vertex_states(struct blitter_context_priv *ctx) |
{ |
struct pipe_context *pipe = ctx->base.pipe; |
unsigned i; |
/* Vertex buffer. */ |
pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, |
&ctx->base.saved_vertex_buffer); |
pipe_resource_reference(&ctx->base.saved_vertex_buffer.buffer, NULL); |
/* Vertex elements. */ |
pipe->bind_vertex_elements_state(pipe, ctx->base.saved_velem_state); |
ctx->base.saved_velem_state = INVALID_PTR; |
/* Vertex shader. */ |
pipe->bind_vs_state(pipe, ctx->base.saved_vs); |
ctx->base.saved_vs = INVALID_PTR; |
/* Geometry shader. */ |
if (ctx->has_geometry_shader) { |
pipe->bind_gs_state(pipe, ctx->base.saved_gs); |
ctx->base.saved_gs = INVALID_PTR; |
} |
/* Stream outputs. */ |
if (ctx->has_stream_out) { |
pipe->set_stream_output_targets(pipe, |
ctx->base.saved_num_so_targets, |
ctx->base.saved_so_targets, ~0); |
for (i = 0; i < ctx->base.saved_num_so_targets; i++) |
pipe_so_target_reference(&ctx->base.saved_so_targets[i], NULL); |
ctx->base.saved_num_so_targets = ~0; |
} |
/* Rasterizer. */ |
pipe->bind_rasterizer_state(pipe, ctx->base.saved_rs_state); |
ctx->base.saved_rs_state = INVALID_PTR; |
} |
static void blitter_check_saved_fragment_states(struct blitter_context_priv *ctx) |
{ |
assert(ctx->base.saved_fs != INVALID_PTR); |
assert(ctx->base.saved_dsa_state != INVALID_PTR); |
assert(ctx->base.saved_blend_state != INVALID_PTR); |
} |
static void blitter_restore_fragment_states(struct blitter_context_priv *ctx) |
{ |
struct pipe_context *pipe = ctx->base.pipe; |
/* Fragment shader. */ |
ctx->bind_fs_state(pipe, ctx->base.saved_fs); |
ctx->base.saved_fs = INVALID_PTR; |
/* Depth, stencil, alpha. */ |
pipe->bind_depth_stencil_alpha_state(pipe, ctx->base.saved_dsa_state); |
ctx->base.saved_dsa_state = INVALID_PTR; |
/* Blend state. */ |
pipe->bind_blend_state(pipe, ctx->base.saved_blend_state); |
ctx->base.saved_blend_state = INVALID_PTR; |
/* Sample mask. */ |
if (ctx->base.is_sample_mask_saved) { |
pipe->set_sample_mask(pipe, ctx->base.saved_sample_mask); |
ctx->base.is_sample_mask_saved = FALSE; |
} |
/* Miscellaneous states. */ |
/* XXX check whether these are saved and whether they need to be restored |
* (depending on the operation) */ |
pipe->set_stencil_ref(pipe, &ctx->base.saved_stencil_ref); |
pipe->set_viewport_states(pipe, 0, 1, &ctx->base.saved_viewport); |
} |
static void blitter_check_saved_fb_state(struct blitter_context_priv *ctx) |
{ |
assert(ctx->base.saved_fb_state.nr_cbufs != ~0); |
} |
static void blitter_disable_render_cond(struct blitter_context_priv *ctx) |
{ |
struct pipe_context *pipe = ctx->base.pipe; |
if (ctx->base.saved_render_cond_query) { |
pipe->render_condition(pipe, NULL, FALSE, 0); |
} |
} |
static void blitter_restore_render_cond(struct blitter_context_priv *ctx) |
{ |
struct pipe_context *pipe = ctx->base.pipe; |
if (ctx->base.saved_render_cond_query) { |
pipe->render_condition(pipe, ctx->base.saved_render_cond_query, |
ctx->base.saved_render_cond_cond, |
ctx->base.saved_render_cond_mode); |
ctx->base.saved_render_cond_query = NULL; |
} |
} |
static void blitter_restore_fb_state(struct blitter_context_priv *ctx) |
{ |
struct pipe_context *pipe = ctx->base.pipe; |
pipe->set_framebuffer_state(pipe, &ctx->base.saved_fb_state); |
util_unreference_framebuffer_state(&ctx->base.saved_fb_state); |
} |
static void blitter_check_saved_textures(struct blitter_context_priv *ctx) |
{ |
assert(ctx->base.saved_num_sampler_states != ~0); |
assert(ctx->base.saved_num_sampler_views != ~0); |
} |
static void blitter_restore_textures(struct blitter_context_priv *ctx) |
{ |
struct pipe_context *pipe = ctx->base.pipe; |
unsigned i; |
/* Fragment sampler states. */ |
pipe->bind_fragment_sampler_states(pipe, |
ctx->base.saved_num_sampler_states, |
ctx->base.saved_sampler_states); |
ctx->base.saved_num_sampler_states = ~0; |
/* Fragment sampler views. */ |
pipe->set_fragment_sampler_views(pipe, |
ctx->base.saved_num_sampler_views, |
ctx->base.saved_sampler_views); |
for (i = 0; i < ctx->base.saved_num_sampler_views; i++) |
pipe_sampler_view_reference(&ctx->base.saved_sampler_views[i], NULL); |
ctx->base.saved_num_sampler_views = ~0; |
} |
static void blitter_set_rectangle(struct blitter_context_priv *ctx, |
int x1, int y1, int x2, int y2, |
float depth) |
{ |
int i; |
/* set vertex positions */ |
ctx->vertices[0][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v0.x*/ |
ctx->vertices[0][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v0.y*/ |
ctx->vertices[1][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v1.x*/ |
ctx->vertices[1][0][1] = (float)y1 / ctx->dst_height * 2.0f - 1.0f; /*v1.y*/ |
ctx->vertices[2][0][0] = (float)x2 / ctx->dst_width * 2.0f - 1.0f; /*v2.x*/ |
ctx->vertices[2][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v2.y*/ |
ctx->vertices[3][0][0] = (float)x1 / ctx->dst_width * 2.0f - 1.0f; /*v3.x*/ |
ctx->vertices[3][0][1] = (float)y2 / ctx->dst_height * 2.0f - 1.0f; /*v3.y*/ |
for (i = 0; i < 4; i++) |
ctx->vertices[i][0][2] = depth; /*z*/ |
/* viewport */ |
ctx->viewport.scale[0] = 0.5f * ctx->dst_width; |
ctx->viewport.scale[1] = 0.5f * ctx->dst_height; |
ctx->viewport.scale[2] = 1.0f; |
ctx->viewport.scale[3] = 1.0f; |
ctx->viewport.translate[0] = 0.5f * ctx->dst_width; |
ctx->viewport.translate[1] = 0.5f * ctx->dst_height; |
ctx->viewport.translate[2] = 0.0f; |
ctx->viewport.translate[3] = 0.0f; |
ctx->base.pipe->set_viewport_states(ctx->base.pipe, 0, 1, &ctx->viewport); |
} |
static void blitter_set_clear_color(struct blitter_context_priv *ctx, |
const union pipe_color_union *color) |
{ |
int i; |
if (color) { |
for (i = 0; i < 4; i++) { |
uint32_t *uiverts = (uint32_t *)ctx->vertices[i][1]; |
uiverts[0] = color->ui[0]; |
uiverts[1] = color->ui[1]; |
uiverts[2] = color->ui[2]; |
uiverts[3] = color->ui[3]; |
} |
} else { |
for (i = 0; i < 4; i++) { |
ctx->vertices[i][1][0] = 0; |
ctx->vertices[i][1][1] = 0; |
ctx->vertices[i][1][2] = 0; |
ctx->vertices[i][1][3] = 0; |
} |
} |
} |
static void get_texcoords(struct pipe_sampler_view *src, |
unsigned src_width0, unsigned src_height0, |
int x1, int y1, int x2, int y2, |
float out[4]) |
{ |
struct pipe_resource *tex = src->texture; |
unsigned level = src->u.tex.first_level; |
boolean normalized = tex->target != PIPE_TEXTURE_RECT && |
tex->nr_samples <= 1; |
if (normalized) { |
out[0] = x1 / (float)u_minify(src_width0, level); |
out[1] = y1 / (float)u_minify(src_height0, level); |
out[2] = x2 / (float)u_minify(src_width0, level); |
out[3] = y2 / (float)u_minify(src_height0, level); |
} else { |
out[0] = (float) x1; |
out[1] = (float) y1; |
out[2] = (float) x2; |
out[3] = (float) y2; |
} |
} |
static void set_texcoords_in_vertices(const float coord[4], |
float *out, unsigned stride) |
{ |
out[0] = coord[0]; /*t0.s*/ |
out[1] = coord[1]; /*t0.t*/ |
out += stride; |
out[0] = coord[2]; /*t1.s*/ |
out[1] = coord[1]; /*t1.t*/ |
out += stride; |
out[0] = coord[2]; /*t2.s*/ |
out[1] = coord[3]; /*t2.t*/ |
out += stride; |
out[0] = coord[0]; /*t3.s*/ |
out[1] = coord[3]; /*t3.t*/ |
} |
static void blitter_set_texcoords(struct blitter_context_priv *ctx, |
struct pipe_sampler_view *src, |
unsigned src_width0, unsigned src_height0, |
unsigned layer, unsigned sample, |
int x1, int y1, int x2, int y2) |
{ |
unsigned i; |
float coord[4]; |
float face_coord[4][2]; |
get_texcoords(src, src_width0, src_height0, x1, y1, x2, y2, coord); |
if (src->texture->target == PIPE_TEXTURE_CUBE || |
src->texture->target == PIPE_TEXTURE_CUBE_ARRAY) { |
set_texcoords_in_vertices(coord, &face_coord[0][0], 2); |
util_map_texcoords2d_onto_cubemap(layer % 6, |
/* pointer, stride in floats */ |
&face_coord[0][0], 2, |
&ctx->vertices[0][1][0], 8); |
} else { |
set_texcoords_in_vertices(coord, &ctx->vertices[0][1][0], 8); |
} |
/* Set the layer. */ |
switch (src->texture->target) { |
case PIPE_TEXTURE_3D: |
{ |
float r = layer / (float)u_minify(src->texture->depth0, |
src->u.tex.first_level); |
for (i = 0; i < 4; i++) |
ctx->vertices[i][1][2] = r; /*r*/ |
} |
break; |
case PIPE_TEXTURE_1D_ARRAY: |
for (i = 0; i < 4; i++) |
ctx->vertices[i][1][1] = (float) layer; /*t*/ |
break; |
case PIPE_TEXTURE_2D_ARRAY: |
for (i = 0; i < 4; i++) { |
ctx->vertices[i][1][2] = (float) layer; /*r*/ |
ctx->vertices[i][1][3] = (float) sample; /*q*/ |
} |
break; |
case PIPE_TEXTURE_CUBE_ARRAY: |
for (i = 0; i < 4; i++) |
ctx->vertices[i][1][3] = (float) (layer / 6); /*w*/ |
break; |
case PIPE_TEXTURE_2D: |
for (i = 0; i < 4; i++) { |
ctx->vertices[i][1][3] = (float) sample; /*r*/ |
} |
break; |
default:; |
} |
} |
static void blitter_set_dst_dimensions(struct blitter_context_priv *ctx, |
unsigned width, unsigned height) |
{ |
ctx->dst_width = width; |
ctx->dst_height = height; |
} |
static void *blitter_get_fs_texfetch_col(struct blitter_context_priv *ctx, |
enum pipe_texture_target target, |
unsigned nr_samples) |
{ |
struct pipe_context *pipe = ctx->base.pipe; |
assert(target < PIPE_MAX_TEXTURE_TYPES); |
if (nr_samples > 1) { |
void **shader = &ctx->fs_texfetch_col_msaa[target]; |
/* Create the fragment shader on-demand. */ |
if (!*shader) { |
unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target, |
nr_samples); |
*shader = util_make_fs_blit_msaa_color(pipe, tgsi_tex); |
} |
return *shader; |
} else { |
void **shader = &ctx->fs_texfetch_col[target]; |
/* Create the fragment shader on-demand. */ |
if (!*shader) { |
unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0); |
*shader = |
util_make_fragment_tex_shader(pipe, tgsi_tex, |
TGSI_INTERPOLATE_LINEAR); |
} |
return *shader; |
} |
} |
static INLINE |
void *blitter_get_fs_texfetch_depth(struct blitter_context_priv *ctx, |
enum pipe_texture_target target, |
unsigned nr_samples) |
{ |
struct pipe_context *pipe = ctx->base.pipe; |
assert(target < PIPE_MAX_TEXTURE_TYPES); |
if (nr_samples > 1) { |
void **shader = &ctx->fs_texfetch_depth_msaa[target]; |
/* Create the fragment shader on-demand. */ |
if (!*shader) { |
unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target, |
nr_samples); |
*shader = |
util_make_fs_blit_msaa_depth(pipe, tgsi_tex); |
} |
return *shader; |
} else { |
void **shader = &ctx->fs_texfetch_depth[target]; |
/* Create the fragment shader on-demand. */ |
if (!*shader) { |
unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0); |
*shader = |
util_make_fragment_tex_shader_writedepth(pipe, tgsi_tex, |
TGSI_INTERPOLATE_LINEAR); |
} |
return *shader; |
} |
} |
static INLINE |
void *blitter_get_fs_texfetch_depthstencil(struct blitter_context_priv *ctx, |
enum pipe_texture_target target, |
unsigned nr_samples) |
{ |
struct pipe_context *pipe = ctx->base.pipe; |
assert(target < PIPE_MAX_TEXTURE_TYPES); |
if (nr_samples > 1) { |
void **shader = &ctx->fs_texfetch_depthstencil_msaa[target]; |
/* Create the fragment shader on-demand. */ |
if (!*shader) { |
unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target, |
nr_samples); |
*shader = |
util_make_fs_blit_msaa_depthstencil(pipe, tgsi_tex); |
} |
return *shader; |
} else { |
void **shader = &ctx->fs_texfetch_depthstencil[target]; |
/* Create the fragment shader on-demand. */ |
if (!*shader) { |
unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0); |
*shader = |
util_make_fragment_tex_shader_writedepthstencil(pipe, tgsi_tex, |
TGSI_INTERPOLATE_LINEAR); |
} |
return *shader; |
} |
} |
static INLINE |
void *blitter_get_fs_texfetch_stencil(struct blitter_context_priv *ctx, |
enum pipe_texture_target target, |
unsigned nr_samples) |
{ |
struct pipe_context *pipe = ctx->base.pipe; |
assert(target < PIPE_MAX_TEXTURE_TYPES); |
if (nr_samples > 1) { |
void **shader = &ctx->fs_texfetch_stencil_msaa[target]; |
/* Create the fragment shader on-demand. */ |
if (!*shader) { |
unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target, |
nr_samples); |
*shader = |
util_make_fs_blit_msaa_stencil(pipe, tgsi_tex); |
} |
return *shader; |
} else { |
void **shader = &ctx->fs_texfetch_stencil[target]; |
/* Create the fragment shader on-demand. */ |
if (!*shader) { |
unsigned tgsi_tex = util_pipe_tex_to_tgsi_tex(target, 0); |
*shader = |
util_make_fragment_tex_shader_writestencil(pipe, tgsi_tex, |
TGSI_INTERPOLATE_LINEAR); |
} |
return *shader; |
} |
} |
void util_blitter_cache_all_shaders(struct blitter_context *blitter) |
{ |
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; |
struct pipe_screen *screen = blitter->pipe->screen; |
unsigned i, target, max_samples; |
boolean has_arraytex, has_cubearraytex; |
max_samples = ctx->has_texture_multisample ? 2 : 1; |
has_arraytex = screen->get_param(screen, |
PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS) != 0; |
has_cubearraytex = screen->get_param(screen, |
PIPE_CAP_CUBE_MAP_ARRAY) != 0; |
/* It only matters if i <= 1 or > 1. */ |
for (i = 1; i <= max_samples; i++) { |
for (target = PIPE_TEXTURE_1D; target < PIPE_MAX_TEXTURE_TYPES; target++) { |
if (!has_arraytex && |
(target == PIPE_TEXTURE_1D_ARRAY || |
target == PIPE_TEXTURE_2D_ARRAY)) { |
continue; |
} |
if (!has_cubearraytex && |
(target == PIPE_TEXTURE_CUBE_ARRAY)) |
continue; |
if (i > 1 && |
(target != PIPE_TEXTURE_2D && |
target != PIPE_TEXTURE_2D_ARRAY)) |
continue; |
blitter_get_fs_texfetch_col(ctx, target, i); |
blitter_get_fs_texfetch_depth(ctx, target, i); |
if (ctx->has_stencil_export) { |
blitter_get_fs_texfetch_depthstencil(ctx, target, i); |
blitter_get_fs_texfetch_stencil(ctx, target, i); |
} |
} |
} |
} |
static void blitter_set_common_draw_rect_state(struct blitter_context_priv *ctx, |
boolean scissor) |
{ |
struct pipe_context *pipe = ctx->base.pipe; |
pipe->bind_rasterizer_state(pipe, scissor ? ctx->rs_state_scissor |
: ctx->rs_state); |
pipe->bind_vs_state(pipe, ctx->vs); |
if (ctx->has_geometry_shader) |
pipe->bind_gs_state(pipe, NULL); |
if (ctx->has_stream_out) |
pipe->set_stream_output_targets(pipe, 0, NULL, 0); |
} |
static void blitter_draw(struct blitter_context_priv *ctx, |
int x1, int y1, int x2, int y2, float depth) |
{ |
struct pipe_resource *buf = NULL; |
unsigned offset = 0; |
blitter_set_rectangle(ctx, x1, y1, x2, y2, depth); |
u_upload_data(ctx->upload, 0, sizeof(ctx->vertices), ctx->vertices, |
&offset, &buf); |
u_upload_unmap(ctx->upload); |
util_draw_vertex_buffer(ctx->base.pipe, NULL, buf, ctx->base.vb_slot, |
offset, PIPE_PRIM_TRIANGLE_FAN, 4, 2); |
pipe_resource_reference(&buf, NULL); |
} |
void util_blitter_draw_rectangle(struct blitter_context *blitter, |
int x1, int y1, int x2, int y2, float depth, |
enum blitter_attrib_type type, |
const union pipe_color_union *attrib) |
{ |
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; |
switch (type) { |
case UTIL_BLITTER_ATTRIB_COLOR: |
blitter_set_clear_color(ctx, attrib); |
break; |
case UTIL_BLITTER_ATTRIB_TEXCOORD: |
set_texcoords_in_vertices(attrib->f, &ctx->vertices[0][1][0], 8); |
break; |
default:; |
} |
blitter_draw(ctx, x1, y1, x2, y2, depth); |
} |
static void util_blitter_clear_custom(struct blitter_context *blitter, |
unsigned width, unsigned height, |
unsigned clear_buffers, |
const union pipe_color_union *color, |
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; |
struct pipe_stencil_ref sr = { { 0 } }; |
blitter_set_running_flag(ctx); |
blitter_check_saved_vertex_states(ctx); |
blitter_check_saved_fragment_states(ctx); |
blitter_disable_render_cond(ctx); |
/* bind states */ |
if (custom_blend) { |
pipe->bind_blend_state(pipe, custom_blend); |
} else if (clear_buffers & PIPE_CLEAR_COLOR) { |
pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA]); |
} else { |
pipe->bind_blend_state(pipe, ctx->blend[0]); |
} |
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); |
} 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) { |
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil); |
} 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_vertex_elements_state(pipe, ctx->velem_state); |
ctx->bind_fs_state(pipe, ctx->fs_write_all_cbufs); |
pipe->set_sample_mask(pipe, ~0); |
blitter_set_common_draw_rect_state(ctx, FALSE); |
blitter_set_dst_dimensions(ctx, width, height); |
blitter->draw_rectangle(blitter, 0, 0, width, height, (float) depth, |
UTIL_BLITTER_ATTRIB_COLOR, color); |
blitter_restore_vertex_states(ctx); |
blitter_restore_fragment_states(ctx); |
blitter_restore_render_cond(ctx); |
blitter_unset_running_flag(ctx); |
} |
void util_blitter_clear(struct blitter_context *blitter, |
unsigned width, unsigned height, |
unsigned clear_buffers, |
const union pipe_color_union *color, |
double depth, unsigned stencil) |
{ |
util_blitter_clear_custom(blitter, width, height, |
clear_buffers, color, depth, stencil, |
NULL, NULL); |
} |
void util_blitter_custom_clear_depth(struct blitter_context *blitter, |
unsigned width, unsigned height, |
double depth, void *custom_dsa) |
{ |
static const union pipe_color_union color; |
util_blitter_clear_custom(blitter, width, height, 0, &color, depth, 0, |
NULL, custom_dsa); |
} |
void util_blitter_default_dst_texture(struct pipe_surface *dst_templ, |
struct pipe_resource *dst, |
unsigned dstlevel, |
unsigned dstz) |
{ |
memset(dst_templ, 0, sizeof(*dst_templ)); |
dst_templ->format = util_format_linear(dst->format); |
dst_templ->u.tex.level = dstlevel; |
dst_templ->u.tex.first_layer = dstz; |
dst_templ->u.tex.last_layer = dstz; |
} |
static struct pipe_surface * |
util_blitter_get_next_surface_layer(struct pipe_context *pipe, |
struct pipe_surface *surf) |
{ |
struct pipe_surface dst_templ; |
memset(&dst_templ, 0, sizeof(dst_templ)); |
dst_templ.format = surf->format; |
dst_templ.u.tex.level = surf->u.tex.level; |
dst_templ.u.tex.first_layer = surf->u.tex.first_layer + 1; |
dst_templ.u.tex.last_layer = surf->u.tex.last_layer + 1; |
return pipe->create_surface(pipe, surf->texture, &dst_templ); |
} |
void util_blitter_default_src_texture(struct pipe_sampler_view *src_templ, |
struct pipe_resource *src, |
unsigned srclevel) |
{ |
memset(src_templ, 0, sizeof(*src_templ)); |
src_templ->format = util_format_linear(src->format); |
src_templ->u.tex.first_level = srclevel; |
src_templ->u.tex.last_level = srclevel; |
src_templ->u.tex.first_layer = 0; |
src_templ->u.tex.last_layer = |
src->target == PIPE_TEXTURE_3D ? u_minify(src->depth0, srclevel) - 1 |
: src->array_size - 1; |
src_templ->swizzle_r = PIPE_SWIZZLE_RED; |
src_templ->swizzle_g = PIPE_SWIZZLE_GREEN; |
src_templ->swizzle_b = PIPE_SWIZZLE_BLUE; |
src_templ->swizzle_a = PIPE_SWIZZLE_ALPHA; |
} |
static boolean is_blit_generic_supported(struct blitter_context *blitter, |
const struct pipe_resource *dst, |
enum pipe_format dst_format, |
const struct pipe_resource *src, |
enum pipe_format src_format, |
unsigned mask) |
{ |
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; |
struct pipe_screen *screen = ctx->base.pipe->screen; |
if (dst) { |
unsigned bind; |
const struct util_format_description *desc = |
util_format_description(dst_format); |
boolean dst_has_stencil = util_format_has_stencil(desc); |
/* Stencil export must be supported for stencil copy. */ |
if ((mask & PIPE_MASK_S) && dst_has_stencil && |
!ctx->has_stencil_export) { |
return FALSE; |
} |
if (dst_has_stencil || util_format_has_depth(desc)) |
bind = PIPE_BIND_DEPTH_STENCIL; |
else |
bind = PIPE_BIND_RENDER_TARGET; |
if (!screen->is_format_supported(screen, dst_format, dst->target, |
dst->nr_samples, bind)) { |
return FALSE; |
} |
} |
if (src) { |
if (src->nr_samples > 1 && !ctx->has_texture_multisample) { |
return FALSE; |
} |
if (!screen->is_format_supported(screen, src_format, src->target, |
src->nr_samples, PIPE_BIND_SAMPLER_VIEW)) { |
return FALSE; |
} |
/* Check stencil sampler support for stencil copy. */ |
if (mask & PIPE_MASK_S) { |
if (util_format_has_stencil(util_format_description(src_format))) { |
enum pipe_format stencil_format = |
util_format_stencil_only(src_format); |
assert(stencil_format != PIPE_FORMAT_NONE); |
if (stencil_format != src_format && |
!screen->is_format_supported(screen, stencil_format, |
src->target, src->nr_samples, |
PIPE_BIND_SAMPLER_VIEW)) { |
return FALSE; |
} |
} |
} |
} |
return TRUE; |
} |
boolean util_blitter_is_copy_supported(struct blitter_context *blitter, |
const struct pipe_resource *dst, |
const struct pipe_resource *src, |
unsigned mask) |
{ |
return is_blit_generic_supported(blitter, dst, dst->format, |
src, src->format, mask); |
} |
boolean util_blitter_is_blit_supported(struct blitter_context *blitter, |
const struct pipe_blit_info *info) |
{ |
return is_blit_generic_supported(blitter, |
info->dst.resource, info->dst.format, |
info->src.resource, info->src.format, |
info->mask); |
} |
void util_blitter_copy_texture(struct blitter_context *blitter, |
struct pipe_resource *dst, |
unsigned dst_level, |
unsigned dstx, unsigned dsty, unsigned dstz, |
struct pipe_resource *src, |
unsigned src_level, |
const struct pipe_box *srcbox, unsigned mask, |
boolean copy_all_samples) |
{ |
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; |
struct pipe_context *pipe = ctx->base.pipe; |
struct pipe_surface *dst_view, dst_templ; |
struct pipe_sampler_view src_templ, *src_view; |
struct pipe_box dstbox; |
assert(dst && src); |
assert(src->target < PIPE_MAX_TEXTURE_TYPES); |
u_box_3d(dstx, dsty, dstz, abs(srcbox->width), abs(srcbox->height), |
abs(srcbox->depth), &dstbox); |
/* Initialize the surface. */ |
util_blitter_default_dst_texture(&dst_templ, dst, dst_level, dstz); |
dst_view = pipe->create_surface(pipe, dst, &dst_templ); |
/* Initialize the sampler view. */ |
util_blitter_default_src_texture(&src_templ, src, src_level); |
src_view = pipe->create_sampler_view(pipe, src, &src_templ); |
/* Copy. */ |
util_blitter_blit_generic(blitter, dst_view, &dstbox, |
src_view, srcbox, src->width0, src->height0, |
mask, PIPE_TEX_FILTER_NEAREST, NULL, |
copy_all_samples); |
pipe_surface_reference(&dst_view, NULL); |
pipe_sampler_view_reference(&src_view, NULL); |
} |
void util_blitter_blit_generic(struct blitter_context *blitter, |
struct pipe_surface *dst, |
const struct pipe_box *dstbox, |
struct pipe_sampler_view *src, |
const struct pipe_box *srcbox, |
unsigned src_width0, unsigned src_height0, |
unsigned mask, unsigned filter, |
const struct pipe_scissor_state *scissor, |
boolean copy_all_samples) |
{ |
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; |
struct pipe_context *pipe = ctx->base.pipe; |
struct pipe_framebuffer_state fb_state; |
enum pipe_texture_target src_target = src->texture->target; |
unsigned src_samples = src->texture->nr_samples; |
boolean has_depth, has_stencil, has_color; |
boolean blit_stencil, blit_depth, blit_color; |
void *sampler_state; |
const struct util_format_description *src_desc = |
util_format_description(src->format); |
const struct util_format_description *dst_desc = |
util_format_description(dst->format); |
has_color = src_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS && |
dst_desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS; |
has_depth = util_format_has_depth(src_desc) && |
util_format_has_depth(dst_desc); |
has_stencil = util_format_has_stencil(src_desc) && |
util_format_has_stencil(dst_desc); |
blit_color = has_color && (mask & PIPE_MASK_RGBA); |
blit_depth = has_depth && (mask & PIPE_MASK_Z); |
blit_stencil = has_stencil && (mask & PIPE_MASK_S) && |
ctx->has_stencil_export; |
if (!blit_stencil && !blit_depth && !blit_color) { |
return; |
} |
/* Check whether the states are properly saved. */ |
blitter_set_running_flag(ctx); |
blitter_check_saved_vertex_states(ctx); |
blitter_check_saved_fragment_states(ctx); |
blitter_check_saved_textures(ctx); |
blitter_check_saved_fb_state(ctx); |
blitter_disable_render_cond(ctx); |
/* Initialize framebuffer state. */ |
fb_state.width = dst->width; |
fb_state.height = dst->height; |
fb_state.nr_cbufs = blit_depth || blit_stencil ? 0 : 1; |
fb_state.cbufs[0] = NULL; |
fb_state.zsbuf = NULL; |
if (blit_depth || blit_stencil) { |
pipe->bind_blend_state(pipe, ctx->blend[0]); |
if (blit_depth && blit_stencil) { |
pipe->bind_depth_stencil_alpha_state(pipe, |
ctx->dsa_write_depth_stencil); |
ctx->bind_fs_state(pipe, |
blitter_get_fs_texfetch_depthstencil(ctx, src_target, |
src_samples)); |
} else if (blit_depth) { |
pipe->bind_depth_stencil_alpha_state(pipe, |
ctx->dsa_write_depth_keep_stencil); |
ctx->bind_fs_state(pipe, |
blitter_get_fs_texfetch_depth(ctx, src_target, |
src_samples)); |
} else { /* is_stencil */ |
pipe->bind_depth_stencil_alpha_state(pipe, |
ctx->dsa_keep_depth_write_stencil); |
ctx->bind_fs_state(pipe, |
blitter_get_fs_texfetch_stencil(ctx, src_target, |
src_samples)); |
} |
} else { |
pipe->bind_blend_state(pipe, ctx->blend[mask & PIPE_MASK_RGBA]); |
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); |
ctx->bind_fs_state(pipe, |
blitter_get_fs_texfetch_col(ctx, src_target, |
src_samples)); |
} |
/* Set the linear filter only for scaled color non-MSAA blits. */ |
if (filter == PIPE_TEX_FILTER_LINEAR && |
!blit_depth && !blit_stencil && |
src_samples <= 1 && |
(dstbox->width != abs(srcbox->width) || |
dstbox->height != abs(srcbox->height))) { |
if (src_target == PIPE_TEXTURE_RECT) { |
sampler_state = ctx->sampler_state_rect_linear; |
} else { |
sampler_state = ctx->sampler_state_linear; |
} |
} else { |
if (src_target == PIPE_TEXTURE_RECT) { |
sampler_state = ctx->sampler_state_rect; |
} else { |
sampler_state = ctx->sampler_state; |
} |
} |
/* Set samplers. */ |
if (blit_depth && blit_stencil) { |
/* Setup two samplers, one for depth and the other one for stencil. */ |
struct pipe_sampler_view templ; |
struct pipe_sampler_view *views[2]; |
void *samplers[2] = {sampler_state, sampler_state}; |
templ = *src; |
templ.format = util_format_stencil_only(templ.format); |
assert(templ.format != PIPE_FORMAT_NONE); |
views[0] = src; |
views[1] = pipe->create_sampler_view(pipe, src->texture, &templ); |
pipe->set_fragment_sampler_views(pipe, 2, views); |
pipe->bind_fragment_sampler_states(pipe, 2, samplers); |
pipe_sampler_view_reference(&views[1], NULL); |
} else if (blit_stencil) { |
/* Set a stencil-only sampler view for it not to sample depth instead. */ |
struct pipe_sampler_view templ; |
struct pipe_sampler_view *view; |
templ = *src; |
templ.format = util_format_stencil_only(templ.format); |
assert(templ.format != PIPE_FORMAT_NONE); |
view = pipe->create_sampler_view(pipe, src->texture, &templ); |
pipe->set_fragment_sampler_views(pipe, 1, &view); |
pipe->bind_fragment_sampler_states(pipe, 1, &sampler_state); |
pipe_sampler_view_reference(&view, NULL); |
} else { |
pipe->set_fragment_sampler_views(pipe, 1, &src); |
pipe->bind_fragment_sampler_states(pipe, 1, &sampler_state); |
} |
pipe->bind_vertex_elements_state(pipe, ctx->velem_state); |
if (scissor) { |
pipe->set_scissor_states(pipe, 0, 1, scissor); |
} |
blitter_set_common_draw_rect_state(ctx, scissor != NULL); |
blitter_set_dst_dimensions(ctx, dst->width, dst->height); |
if ((src_target == PIPE_TEXTURE_1D || |
src_target == PIPE_TEXTURE_2D || |
src_target == PIPE_TEXTURE_RECT) && |
src_samples <= 1) { |
/* Draw the quad with the draw_rectangle callback. */ |
/* Set texture coordinates. - use a pipe color union |
* for interface purposes. |
* XXX pipe_color_union is a wrong name since we use that to set |
* texture coordinates too. |
*/ |
union pipe_color_union coord; |
get_texcoords(src, src_width0, src_height0, srcbox->x, srcbox->y, |
srcbox->x+srcbox->width, srcbox->y+srcbox->height, coord.f); |
/* Set framebuffer state. */ |
if (blit_depth || blit_stencil) { |
fb_state.zsbuf = dst; |
} else { |
fb_state.cbufs[0] = dst; |
} |
pipe->set_framebuffer_state(pipe, &fb_state); |
/* Draw. */ |
pipe->set_sample_mask(pipe, ~0); |
blitter->draw_rectangle(blitter, dstbox->x, dstbox->y, |
dstbox->x + dstbox->width, |
dstbox->y + dstbox->height, 0, |
UTIL_BLITTER_ATTRIB_TEXCOORD, &coord); |
} else { |
/* Draw the quad with the generic codepath. */ |
int z; |
for (z = 0; z < dstbox->depth; z++) { |
struct pipe_surface *old; |
/* Set framebuffer state. */ |
if (blit_depth || blit_stencil) { |
fb_state.zsbuf = dst; |
} else { |
fb_state.cbufs[0] = dst; |
} |
pipe->set_framebuffer_state(pipe, &fb_state); |
/* See if we need to blit a multisample or singlesample buffer. */ |
if (copy_all_samples && |
src_samples == dst->texture->nr_samples && |
dst->texture->nr_samples > 1) { |
unsigned i, max_sample = MAX2(dst->texture->nr_samples, 1) - 1; |
for (i = 0; i <= max_sample; i++) { |
pipe->set_sample_mask(pipe, 1 << i); |
blitter_set_texcoords(ctx, src, src_width0, src_height0, |
srcbox->z + z, |
i, srcbox->x, srcbox->y, |
srcbox->x + srcbox->width, |
srcbox->y + srcbox->height); |
blitter_draw(ctx, dstbox->x, dstbox->y, |
dstbox->x + dstbox->width, |
dstbox->y + dstbox->height, 0); |
} |
} else { |
pipe->set_sample_mask(pipe, ~0); |
blitter_set_texcoords(ctx, src, src_width0, src_height0, |
srcbox->z + z, 0, |
srcbox->x, srcbox->y, |
srcbox->x + srcbox->width, |
srcbox->y + srcbox->height); |
blitter_draw(ctx, dstbox->x, dstbox->y, |
dstbox->x + dstbox->width, |
dstbox->y + dstbox->height, 0); |
} |
/* Get the next surface or (if this is the last iteration) |
* just unreference the last one. */ |
old = dst; |
if (z < dstbox->depth-1) { |
dst = ctx->base.get_next_surface_layer(ctx->base.pipe, dst); |
} |
if (z) { |
pipe_surface_reference(&old, NULL); |
} |
} |
} |
blitter_restore_vertex_states(ctx); |
blitter_restore_fragment_states(ctx); |
blitter_restore_textures(ctx); |
blitter_restore_fb_state(ctx); |
if (scissor) { |
pipe->set_scissor_states(pipe, 0, 1, &ctx->base.saved_scissor); |
} |
blitter_restore_render_cond(ctx); |
blitter_unset_running_flag(ctx); |
} |
void |
util_blitter_blit(struct blitter_context *blitter, |
const struct pipe_blit_info *info) |
{ |
struct pipe_resource *dst = info->dst.resource; |
struct pipe_resource *src = info->src.resource; |
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; |
struct pipe_context *pipe = ctx->base.pipe; |
struct pipe_surface *dst_view, dst_templ; |
struct pipe_sampler_view src_templ, *src_view; |
/* Initialize the surface. */ |
util_blitter_default_dst_texture(&dst_templ, dst, info->dst.level, |
info->dst.box.z); |
dst_templ.format = info->dst.format; |
dst_view = pipe->create_surface(pipe, dst, &dst_templ); |
/* Initialize the sampler view. */ |
util_blitter_default_src_texture(&src_templ, src, info->src.level); |
src_templ.format = info->src.format; |
src_view = pipe->create_sampler_view(pipe, src, &src_templ); |
/* Copy. */ |
util_blitter_blit_generic(blitter, dst_view, &info->dst.box, |
src_view, &info->src.box, src->width0, src->height0, |
info->mask, info->filter, |
info->scissor_enable ? &info->scissor : NULL, TRUE); |
pipe_surface_reference(&dst_view, NULL); |
pipe_sampler_view_reference(&src_view, NULL); |
} |
/* Clear a region of a color surface to a constant value. */ |
void util_blitter_clear_render_target(struct blitter_context *blitter, |
struct pipe_surface *dstsurf, |
const union pipe_color_union *color, |
unsigned dstx, unsigned dsty, |
unsigned width, unsigned height) |
{ |
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; |
struct pipe_context *pipe = ctx->base.pipe; |
struct pipe_framebuffer_state fb_state; |
assert(dstsurf->texture); |
if (!dstsurf->texture) |
return; |
/* check the saved state */ |
blitter_set_running_flag(ctx); |
blitter_check_saved_vertex_states(ctx); |
blitter_check_saved_fragment_states(ctx); |
blitter_check_saved_fb_state(ctx); |
blitter_disable_render_cond(ctx); |
/* bind states */ |
pipe->bind_blend_state(pipe, ctx->blend[PIPE_MASK_RGBA]); |
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); |
ctx->bind_fs_state(pipe, ctx->fs_write_one_cbuf); |
pipe->bind_vertex_elements_state(pipe, ctx->velem_state); |
/* set a framebuffer state */ |
fb_state.width = dstsurf->width; |
fb_state.height = dstsurf->height; |
fb_state.nr_cbufs = 1; |
fb_state.cbufs[0] = dstsurf; |
fb_state.zsbuf = 0; |
pipe->set_framebuffer_state(pipe, &fb_state); |
pipe->set_sample_mask(pipe, ~0); |
blitter_set_common_draw_rect_state(ctx, FALSE); |
blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height); |
blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, 0, |
UTIL_BLITTER_ATTRIB_COLOR, color); |
blitter_restore_vertex_states(ctx); |
blitter_restore_fragment_states(ctx); |
blitter_restore_fb_state(ctx); |
blitter_restore_render_cond(ctx); |
blitter_unset_running_flag(ctx); |
} |
/* Clear a region of a depth stencil surface. */ |
void util_blitter_clear_depth_stencil(struct blitter_context *blitter, |
struct pipe_surface *dstsurf, |
unsigned clear_flags, |
double depth, |
unsigned stencil, |
unsigned dstx, unsigned dsty, |
unsigned width, unsigned height) |
{ |
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; |
struct pipe_context *pipe = ctx->base.pipe; |
struct pipe_framebuffer_state fb_state; |
struct pipe_stencil_ref sr = { { 0 } }; |
assert(dstsurf->texture); |
if (!dstsurf->texture) |
return; |
/* check the saved state */ |
blitter_set_running_flag(ctx); |
blitter_check_saved_vertex_states(ctx); |
blitter_check_saved_fragment_states(ctx); |
blitter_check_saved_fb_state(ctx); |
blitter_disable_render_cond(ctx); |
/* bind states */ |
pipe->bind_blend_state(pipe, ctx->blend[0]); |
if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) == PIPE_CLEAR_DEPTHSTENCIL) { |
sr.ref_value[0] = stencil & 0xff; |
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil); |
pipe->set_stencil_ref(pipe, &sr); |
} |
else if (clear_flags & PIPE_CLEAR_DEPTH) { |
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil); |
} |
else if (clear_flags & PIPE_CLEAR_STENCIL) { |
sr.ref_value[0] = stencil & 0xff; |
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_write_stencil); |
pipe->set_stencil_ref(pipe, &sr); |
} |
else |
/* hmm that should be illegal probably, or make it a no-op somewhere */ |
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); |
ctx->bind_fs_state(pipe, ctx->fs_empty); |
pipe->bind_vertex_elements_state(pipe, ctx->velem_state); |
/* set a framebuffer state */ |
fb_state.width = dstsurf->width; |
fb_state.height = dstsurf->height; |
fb_state.nr_cbufs = 0; |
fb_state.cbufs[0] = 0; |
fb_state.zsbuf = dstsurf; |
pipe->set_framebuffer_state(pipe, &fb_state); |
pipe->set_sample_mask(pipe, ~0); |
blitter_set_common_draw_rect_state(ctx, FALSE); |
blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height); |
blitter->draw_rectangle(blitter, dstx, dsty, dstx+width, dsty+height, |
(float) depth, |
UTIL_BLITTER_ATTRIB_NONE, NULL); |
blitter_restore_vertex_states(ctx); |
blitter_restore_fragment_states(ctx); |
blitter_restore_fb_state(ctx); |
blitter_restore_render_cond(ctx); |
blitter_unset_running_flag(ctx); |
} |
/* draw a rectangle across a region using a custom dsa stage - for r600g */ |
void util_blitter_custom_depth_stencil(struct blitter_context *blitter, |
struct pipe_surface *zsurf, |
struct pipe_surface *cbsurf, |
unsigned sample_mask, |
void *dsa_stage, float depth) |
{ |
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; |
struct pipe_context *pipe = ctx->base.pipe; |
struct pipe_framebuffer_state fb_state; |
assert(zsurf->texture); |
if (!zsurf->texture) |
return; |
/* check the saved state */ |
blitter_set_running_flag(ctx); |
blitter_check_saved_vertex_states(ctx); |
blitter_check_saved_fragment_states(ctx); |
blitter_check_saved_fb_state(ctx); |
blitter_disable_render_cond(ctx); |
/* bind states */ |
pipe->bind_blend_state(pipe, cbsurf ? ctx->blend[PIPE_MASK_RGBA] : |
ctx->blend[0]); |
pipe->bind_depth_stencil_alpha_state(pipe, dsa_stage); |
ctx->bind_fs_state(pipe, ctx->fs_empty); |
pipe->bind_vertex_elements_state(pipe, ctx->velem_state); |
/* set a framebuffer state */ |
fb_state.width = zsurf->width; |
fb_state.height = zsurf->height; |
fb_state.nr_cbufs = 1; |
if (cbsurf) { |
fb_state.cbufs[0] = cbsurf; |
fb_state.nr_cbufs = 1; |
} else { |
fb_state.cbufs[0] = NULL; |
fb_state.nr_cbufs = 0; |
} |
fb_state.zsbuf = zsurf; |
pipe->set_framebuffer_state(pipe, &fb_state); |
pipe->set_sample_mask(pipe, sample_mask); |
blitter_set_common_draw_rect_state(ctx, FALSE); |
blitter_set_dst_dimensions(ctx, zsurf->width, zsurf->height); |
blitter->draw_rectangle(blitter, 0, 0, zsurf->width, zsurf->height, depth, |
UTIL_BLITTER_ATTRIB_NONE, NULL); |
blitter_restore_vertex_states(ctx); |
blitter_restore_fragment_states(ctx); |
blitter_restore_fb_state(ctx); |
blitter_restore_render_cond(ctx); |
blitter_unset_running_flag(ctx); |
} |
void util_blitter_copy_buffer(struct blitter_context *blitter, |
struct pipe_resource *dst, |
unsigned dstx, |
struct pipe_resource *src, |
unsigned srcx, |
unsigned size) |
{ |
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; |
struct pipe_context *pipe = ctx->base.pipe; |
struct pipe_vertex_buffer vb; |
struct pipe_stream_output_target *so_target; |
if (srcx >= src->width0 || |
dstx >= dst->width0) { |
return; |
} |
if (srcx + size > src->width0) { |
size = src->width0 - srcx; |
} |
if (dstx + size > dst->width0) { |
size = dst->width0 - dstx; |
} |
/* Drivers not capable of Stream Out should not call this function |
* in the first place. */ |
assert(ctx->has_stream_out); |
/* Some alignment is required. */ |
if (srcx % 4 != 0 || dstx % 4 != 0 || size % 4 != 0 || |
!ctx->has_stream_out) { |
struct pipe_box box; |
u_box_1d(srcx, size, &box); |
util_resource_copy_region(pipe, dst, 0, dstx, 0, 0, src, 0, &box); |
return; |
} |
blitter_set_running_flag(ctx); |
blitter_check_saved_vertex_states(ctx); |
blitter_disable_render_cond(ctx); |
vb.buffer = src; |
vb.buffer_offset = srcx; |
vb.stride = 4; |
pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, &vb); |
pipe->bind_vertex_elements_state(pipe, ctx->velem_state_readbuf[0]); |
pipe->bind_vs_state(pipe, ctx->vs_pos_only); |
if (ctx->has_geometry_shader) |
pipe->bind_gs_state(pipe, NULL); |
pipe->bind_rasterizer_state(pipe, ctx->rs_discard_state); |
so_target = pipe->create_stream_output_target(pipe, dst, dstx, size); |
pipe->set_stream_output_targets(pipe, 1, &so_target, 0); |
util_draw_arrays(pipe, PIPE_PRIM_POINTS, 0, size / 4); |
blitter_restore_vertex_states(ctx); |
blitter_restore_render_cond(ctx); |
blitter_unset_running_flag(ctx); |
pipe_so_target_reference(&so_target, NULL); |
} |
void util_blitter_clear_buffer(struct blitter_context *blitter, |
struct pipe_resource *dst, |
unsigned offset, unsigned size, |
unsigned num_channels, |
const union pipe_color_union *clear_value) |
{ |
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; |
struct pipe_context *pipe = ctx->base.pipe; |
struct pipe_vertex_buffer vb = {0}; |
struct pipe_stream_output_target *so_target; |
assert(num_channels >= 1); |
assert(num_channels <= 4); |
/* IMPORTANT: DON'T DO ANY BOUNDS CHECKING HERE! |
* |
* R600 uses this to initialize texture resources, so width0 might not be |
* what you think it is. |
*/ |
/* Streamout is required. */ |
if (!ctx->has_stream_out) { |
assert(!"Streamout unsupported in util_blitter_clear_buffer()"); |
return; |
} |
/* Some alignment is required. */ |
if (offset % 4 != 0 || size % 4 != 0) { |
assert(!"Bad alignment in util_blitter_clear_buffer()"); |
return; |
} |
u_upload_data(ctx->upload, 0, num_channels*4, clear_value, |
&vb.buffer_offset, &vb.buffer); |
vb.stride = 0; |
blitter_set_running_flag(ctx); |
blitter_check_saved_vertex_states(ctx); |
blitter_disable_render_cond(ctx); |
pipe->set_vertex_buffers(pipe, ctx->base.vb_slot, 1, &vb); |
pipe->bind_vertex_elements_state(pipe, |
ctx->velem_state_readbuf[num_channels-1]); |
pipe->bind_vs_state(pipe, ctx->vs_pos_only); |
if (ctx->has_geometry_shader) |
pipe->bind_gs_state(pipe, NULL); |
pipe->bind_rasterizer_state(pipe, ctx->rs_discard_state); |
so_target = pipe->create_stream_output_target(pipe, dst, offset, size); |
pipe->set_stream_output_targets(pipe, 1, &so_target, 0); |
util_draw_arrays(pipe, PIPE_PRIM_POINTS, 0, size / 4); |
blitter_restore_vertex_states(ctx); |
blitter_restore_render_cond(ctx); |
blitter_unset_running_flag(ctx); |
pipe_so_target_reference(&so_target, NULL); |
pipe_resource_reference(&vb.buffer, NULL); |
} |
/* probably radeon specific */ |
void util_blitter_custom_resolve_color(struct blitter_context *blitter, |
struct pipe_resource *dst, |
unsigned dst_level, |
unsigned dst_layer, |
struct pipe_resource *src, |
unsigned src_layer, |
unsigned sample_mask, |
void *custom_blend, |
enum pipe_format format) |
{ |
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; |
struct pipe_context *pipe = ctx->base.pipe; |
struct pipe_framebuffer_state fb_state; |
struct pipe_surface *srcsurf, *dstsurf, surf_tmpl; |
blitter_set_running_flag(ctx); |
blitter_check_saved_vertex_states(ctx); |
blitter_check_saved_fragment_states(ctx); |
blitter_disable_render_cond(ctx); |
/* bind states */ |
pipe->bind_blend_state(pipe, custom_blend); |
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); |
pipe->bind_vertex_elements_state(pipe, ctx->velem_state); |
ctx->bind_fs_state(pipe, ctx->fs_write_one_cbuf); |
pipe->set_sample_mask(pipe, sample_mask); |
memset(&surf_tmpl, 0, sizeof(surf_tmpl)); |
surf_tmpl.format = format; |
surf_tmpl.u.tex.level = dst_level; |
surf_tmpl.u.tex.first_layer = dst_layer; |
surf_tmpl.u.tex.last_layer = dst_layer; |
dstsurf = pipe->create_surface(pipe, dst, &surf_tmpl); |
surf_tmpl.u.tex.level = 0; |
surf_tmpl.u.tex.first_layer = src_layer; |
surf_tmpl.u.tex.last_layer = src_layer; |
srcsurf = pipe->create_surface(pipe, src, &surf_tmpl); |
/* set a framebuffer state */ |
fb_state.width = src->width0; |
fb_state.height = src->height0; |
fb_state.nr_cbufs = 2; |
fb_state.cbufs[0] = srcsurf; |
fb_state.cbufs[1] = dstsurf; |
fb_state.zsbuf = NULL; |
pipe->set_framebuffer_state(pipe, &fb_state); |
blitter_set_common_draw_rect_state(ctx, FALSE); |
blitter_set_dst_dimensions(ctx, src->width0, src->height0); |
blitter->draw_rectangle(blitter, 0, 0, src->width0, src->height0, |
0, 0, NULL); |
blitter_restore_fb_state(ctx); |
blitter_restore_vertex_states(ctx); |
blitter_restore_fragment_states(ctx); |
blitter_restore_render_cond(ctx); |
blitter_unset_running_flag(ctx); |
pipe_surface_reference(&srcsurf, NULL); |
pipe_surface_reference(&dstsurf, NULL); |
} |
void util_blitter_custom_color(struct blitter_context *blitter, |
struct pipe_surface *dstsurf, |
void *custom_blend) |
{ |
struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; |
struct pipe_context *pipe = ctx->base.pipe; |
struct pipe_framebuffer_state fb_state; |
assert(dstsurf->texture); |
if (!dstsurf->texture) |
return; |
/* check the saved state */ |
blitter_set_running_flag(ctx); |
blitter_check_saved_vertex_states(ctx); |
blitter_check_saved_fragment_states(ctx); |
blitter_check_saved_fb_state(ctx); |
blitter_disable_render_cond(ctx); |
/* bind states */ |
pipe->bind_blend_state(pipe, custom_blend ? custom_blend |
: ctx->blend[PIPE_MASK_RGBA]); |
pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); |
ctx->bind_fs_state(pipe, ctx->fs_write_one_cbuf); |
pipe->bind_vertex_elements_state(pipe, ctx->velem_state); |
pipe->set_sample_mask(pipe, (1ull << MAX2(1, dstsurf->texture->nr_samples)) - 1); |
/* set a framebuffer state */ |
fb_state.width = dstsurf->width; |
fb_state.height = dstsurf->height; |
fb_state.nr_cbufs = 1; |
fb_state.cbufs[0] = dstsurf; |
fb_state.zsbuf = 0; |
pipe->set_framebuffer_state(pipe, &fb_state); |
pipe->set_sample_mask(pipe, ~0); |
blitter_set_common_draw_rect_state(ctx, FALSE); |
blitter_set_dst_dimensions(ctx, dstsurf->width, dstsurf->height); |
blitter->draw_rectangle(blitter, 0, 0, dstsurf->width, dstsurf->height, |
0, 0, NULL); |
blitter_restore_vertex_states(ctx); |
blitter_restore_fragment_states(ctx); |
blitter_restore_fb_state(ctx); |
blitter_restore_render_cond(ctx); |
blitter_unset_running_flag(ctx); |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_blitter.h |
---|
0,0 → 1,531 |
/************************************************************************** |
* |
* Copyright 2009 Marek Olšák <maraeo@gmail.com> |
* |
* 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 TUNGSTEN GRAPHICS 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_BLITTER_H |
#define U_BLITTER_H |
#include "util/u_framebuffer.h" |
#include "util/u_inlines.h" |
#include "pipe/p_state.h" |
/* u_memory.h conflicts with st/mesa */ |
#ifndef Elements |
#define Elements(x) (sizeof(x)/sizeof((x)[0])) |
#endif |
#ifdef __cplusplus |
extern "C" { |
#endif |
struct pipe_context; |
enum blitter_attrib_type { |
UTIL_BLITTER_ATTRIB_NONE, |
UTIL_BLITTER_ATTRIB_COLOR, |
UTIL_BLITTER_ATTRIB_TEXCOORD |
}; |
struct blitter_context |
{ |
/** |
* Draw a rectangle. |
* |
* \param x1 An X coordinate of the top-left corner. |
* \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 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 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 |
* to the GENERIC0 varying slot of a fragment shader. |
* |
* \param attrib See type. |
* |
* \note A driver may optionally override this callback to implement |
* a specialized hardware path for drawing a rectangle, e.g. using |
* a rectangular point sprite. |
*/ |
void (*draw_rectangle)(struct blitter_context *blitter, |
int x1, int y1, int x2, int y2, |
float depth, |
enum blitter_attrib_type type, |
const union pipe_color_union *color); |
/** |
* Get the next surface layer for the pipe surface, i.e. make a copy |
* of the surface and increment the first and last layer by 1. |
* |
* This callback is exposed, so that drivers can override it if needed. |
*/ |
struct pipe_surface *(*get_next_surface_layer)(struct pipe_context *pipe, |
struct pipe_surface *surf); |
/* Whether the blitter is running. */ |
boolean running; |
/* Private members, really. */ |
struct pipe_context *pipe; /**< pipe context */ |
void *saved_blend_state; /**< blend state */ |
void *saved_dsa_state; /**< depth stencil alpha state */ |
void *saved_velem_state; /**< vertex elements state */ |
void *saved_rs_state; /**< rasterizer state */ |
void *saved_fs, *saved_vs, *saved_gs; /**< shaders */ |
struct pipe_framebuffer_state saved_fb_state; /**< framebuffer state */ |
struct pipe_stencil_ref saved_stencil_ref; /**< stencil ref */ |
struct pipe_viewport_state saved_viewport; |
struct pipe_scissor_state saved_scissor; |
boolean is_sample_mask_saved; |
unsigned saved_sample_mask; |
unsigned saved_num_sampler_states; |
void *saved_sampler_states[PIPE_MAX_SAMPLERS]; |
unsigned saved_num_sampler_views; |
struct pipe_sampler_view *saved_sampler_views[PIPE_MAX_SAMPLERS]; |
unsigned vb_slot; |
struct pipe_vertex_buffer saved_vertex_buffer; |
unsigned saved_num_so_targets; |
struct pipe_stream_output_target *saved_so_targets[PIPE_MAX_SO_BUFFERS]; |
struct pipe_query *saved_render_cond_query; |
uint saved_render_cond_mode; |
boolean saved_render_cond_cond; |
}; |
/** |
* Create a blitter context. |
*/ |
struct blitter_context *util_blitter_create(struct pipe_context *pipe); |
/** |
* Destroy a blitter context. |
*/ |
void util_blitter_destroy(struct blitter_context *blitter); |
void util_blitter_cache_all_shaders(struct blitter_context *blitter); |
/** |
* Return the pipe context associated with a blitter context. |
*/ |
static INLINE |
struct pipe_context *util_blitter_get_pipe(struct blitter_context *blitter) |
{ |
return blitter->pipe; |
} |
/** |
* Override PIPE_CAP_TEXTURE_MULTISAMPLE as reported by the driver. |
*/ |
void util_blitter_set_texture_multisample(struct blitter_context *blitter, |
boolean supported); |
/* The default function to draw a rectangle. This can only be used |
* inside of the draw_rectangle callback if the driver overrides it. */ |
void util_blitter_draw_rectangle(struct blitter_context *blitter, |
int x1, int y1, int x2, int y2, float depth, |
enum blitter_attrib_type type, |
const union pipe_color_union *attrib); |
/* |
* These states must be saved before any of the following functions are called: |
* - vertex buffers |
* - vertex elements |
* - vertex shader |
* - geometry shader (if supported) |
* - stream output targets (if supported) |
* - rasterizer state |
*/ |
/** |
* Clear a specified set of currently bound buffers to specified values. |
* |
* These states must be saved in the blitter in addition to the state objects |
* already required to be saved: |
* - fragment shader |
* - depth stencil alpha state |
* - blend state |
*/ |
void util_blitter_clear(struct blitter_context *blitter, |
unsigned width, unsigned height, |
unsigned clear_buffers, |
const union pipe_color_union *color, |
double depth, unsigned stencil); |
/** |
* Check if the blitter (with the help of the driver) can blit between |
* the two resources. |
* The mask is a combination of the PIPE_MASK_* flags. |
* Set to PIPE_MASK_RGBAZS if unsure. |
*/ |
boolean util_blitter_is_copy_supported(struct blitter_context *blitter, |
const struct pipe_resource *dst, |
const struct pipe_resource *src, |
unsigned mask); |
boolean util_blitter_is_blit_supported(struct blitter_context *blitter, |
const struct pipe_blit_info *info); |
/** |
* Copy a block of pixels from one surface to another. |
* |
* These states must be saved in the blitter in addition to the state objects |
* already required to be saved: |
* - fragment shader |
* - depth stencil alpha state |
* - blend state |
* - fragment sampler states |
* - fragment sampler textures |
* - framebuffer state |
* - sample mask |
*/ |
void util_blitter_copy_texture(struct blitter_context *blitter, |
struct pipe_resource *dst, |
unsigned dst_level, |
unsigned dstx, unsigned dsty, unsigned dstz, |
struct pipe_resource *src, |
unsigned src_level, |
const struct pipe_box *srcbox, unsigned mask, |
boolean copy_all_samples); |
/** |
* This is a generic implementation of pipe->blit, which accepts |
* sampler/surface views instead of resources. |
* |
* The layer and mipmap level are specified by the views. |
* |
* Drivers can use this to change resource properties (like format, width, |
* height) by changing how the views interpret them, instead of changing |
* pipe_resource directly. This is used to blit resources of formats which |
* are not renderable. |
* |
* src_width0 and src_height0 are sampler_view-private properties that |
* override pipe_resource. The blitter uses them for computation of texture |
* coordinates. The dst dimensions are supplied through pipe_surface::width |
* and height. |
* |
* The mask is a combination of the PIPE_MASK_* flags. |
* Set to PIPE_MASK_RGBAZS if unsure. |
*/ |
void util_blitter_blit_generic(struct blitter_context *blitter, |
struct pipe_surface *dst, |
const struct pipe_box *dstbox, |
struct pipe_sampler_view *src, |
const struct pipe_box *srcbox, |
unsigned src_width0, unsigned src_height0, |
unsigned mask, unsigned filter, |
const struct pipe_scissor_state *scissor, |
boolean copy_all_samples); |
void util_blitter_blit(struct blitter_context *blitter, |
const struct pipe_blit_info *info); |
/** |
* Helper function to initialize a view for copy_texture_view. |
* The parameters must match copy_texture_view. |
*/ |
void util_blitter_default_dst_texture(struct pipe_surface *dst_templ, |
struct pipe_resource *dst, |
unsigned dstlevel, |
unsigned dstz); |
/** |
* Helper function to initialize a view for copy_texture_view. |
* The parameters must match copy_texture_view. |
*/ |
void util_blitter_default_src_texture(struct pipe_sampler_view *src_templ, |
struct pipe_resource *src, |
unsigned srclevel); |
/** |
* Copy data from one buffer to another using the Stream Output functionality. |
* 4-byte alignment is required, otherwise software fallback is used. |
*/ |
void util_blitter_copy_buffer(struct blitter_context *blitter, |
struct pipe_resource *dst, |
unsigned dstx, |
struct pipe_resource *src, |
unsigned srcx, |
unsigned size); |
/** |
* Clear the contents of a buffer using the Stream Output functionality. |
* 4-byte alignment is required. |
* |
* "num_channels" can be 1, 2, 3, or 4, and specifies if the clear value is |
* R, RG, RGB, or RGBA. |
* |
* For each element, only "num_channels" components of "clear_value" are |
* copied to the buffer, then the offset is incremented by num_channels*4. |
*/ |
void util_blitter_clear_buffer(struct blitter_context *blitter, |
struct pipe_resource *dst, |
unsigned offset, unsigned size, |
unsigned num_channels, |
const union pipe_color_union *clear_value); |
/** |
* Clear a region of a (color) surface to a constant value. |
* |
* These states must be saved in the blitter in addition to the state objects |
* already required to be saved: |
* - fragment shader |
* - depth stencil alpha state |
* - blend state |
* - framebuffer state |
*/ |
void util_blitter_clear_render_target(struct blitter_context *blitter, |
struct pipe_surface *dst, |
const union pipe_color_union *color, |
unsigned dstx, unsigned dsty, |
unsigned width, unsigned height); |
/** |
* Clear a region of a depth-stencil surface, both stencil and depth |
* or only one of them if this is a combined depth-stencil surface. |
* |
* These states must be saved in the blitter in addition to the state objects |
* already required to be saved: |
* - fragment shader |
* - depth stencil alpha state |
* - blend state |
* - framebuffer state |
*/ |
void util_blitter_clear_depth_stencil(struct blitter_context *blitter, |
struct pipe_surface *dst, |
unsigned clear_flags, |
double depth, |
unsigned stencil, |
unsigned dstx, unsigned dsty, |
unsigned width, unsigned height); |
/* The following functions are customized variants of the clear functions. |
* Some drivers use them internally to do things like MSAA resolve |
* and resource decompression. It usually consists of rendering a full-screen |
* quad with a special blend or DSA state. |
*/ |
/* Used by r300g for depth decompression. */ |
void util_blitter_custom_clear_depth(struct blitter_context *blitter, |
unsigned width, unsigned height, |
double depth, void *custom_dsa); |
/* Used by r600g for depth decompression. */ |
void util_blitter_custom_depth_stencil(struct blitter_context *blitter, |
struct pipe_surface *zsurf, |
struct pipe_surface *cbsurf, |
unsigned sample_mask, |
void *dsa_stage, float depth); |
/* Used by r600g for color decompression. */ |
void util_blitter_custom_color(struct blitter_context *blitter, |
struct pipe_surface *dstsurf, |
void *custom_blend); |
/* Used by r600g for MSAA color resolve. */ |
void util_blitter_custom_resolve_color(struct blitter_context *blitter, |
struct pipe_resource *dst, |
unsigned dst_level, |
unsigned dst_layer, |
struct pipe_resource *src, |
unsigned src_layer, |
unsigned sampled_mask, |
void *custom_blend, |
enum pipe_format format); |
/* The functions below should be used to save currently bound constant state |
* objects inside a driver. The objects are automatically restored at the end |
* of the util_blitter_{clear, copy_region, fill_region} functions and then |
* forgotten. |
* |
* States not listed here are not affected by util_blitter. */ |
static INLINE |
void util_blitter_save_blend(struct blitter_context *blitter, |
void *state) |
{ |
blitter->saved_blend_state = state; |
} |
static INLINE |
void util_blitter_save_depth_stencil_alpha(struct blitter_context *blitter, |
void *state) |
{ |
blitter->saved_dsa_state = state; |
} |
static INLINE |
void util_blitter_save_vertex_elements(struct blitter_context *blitter, |
void *state) |
{ |
blitter->saved_velem_state = state; |
} |
static INLINE |
void util_blitter_save_stencil_ref(struct blitter_context *blitter, |
const struct pipe_stencil_ref *state) |
{ |
blitter->saved_stencil_ref = *state; |
} |
static INLINE |
void util_blitter_save_rasterizer(struct blitter_context *blitter, |
void *state) |
{ |
blitter->saved_rs_state = state; |
} |
static INLINE |
void util_blitter_save_fragment_shader(struct blitter_context *blitter, |
void *fs) |
{ |
blitter->saved_fs = fs; |
} |
static INLINE |
void util_blitter_save_vertex_shader(struct blitter_context *blitter, |
void *vs) |
{ |
blitter->saved_vs = vs; |
} |
static INLINE |
void util_blitter_save_geometry_shader(struct blitter_context *blitter, |
void *gs) |
{ |
blitter->saved_gs = gs; |
} |
static INLINE |
void util_blitter_save_framebuffer(struct blitter_context *blitter, |
const struct pipe_framebuffer_state *state) |
{ |
blitter->saved_fb_state.nr_cbufs = 0; /* It's ~0 now, meaning it's unsaved. */ |
util_copy_framebuffer_state(&blitter->saved_fb_state, state); |
} |
static INLINE |
void util_blitter_save_viewport(struct blitter_context *blitter, |
struct pipe_viewport_state *state) |
{ |
blitter->saved_viewport = *state; |
} |
static INLINE |
void util_blitter_save_scissor(struct blitter_context *blitter, |
struct pipe_scissor_state *state) |
{ |
blitter->saved_scissor = *state; |
} |
static INLINE |
void util_blitter_save_fragment_sampler_states( |
struct blitter_context *blitter, |
unsigned num_sampler_states, |
void **sampler_states) |
{ |
assert(num_sampler_states <= Elements(blitter->saved_sampler_states)); |
blitter->saved_num_sampler_states = num_sampler_states; |
memcpy(blitter->saved_sampler_states, sampler_states, |
num_sampler_states * sizeof(void *)); |
} |
static INLINE void |
util_blitter_save_fragment_sampler_views(struct blitter_context *blitter, |
unsigned num_views, |
struct pipe_sampler_view **views) |
{ |
unsigned i; |
assert(num_views <= Elements(blitter->saved_sampler_views)); |
blitter->saved_num_sampler_views = num_views; |
for (i = 0; i < num_views; i++) |
pipe_sampler_view_reference(&blitter->saved_sampler_views[i], |
views[i]); |
} |
static INLINE void |
util_blitter_save_vertex_buffer_slot(struct blitter_context *blitter, |
struct pipe_vertex_buffer *vertex_buffers) |
{ |
pipe_resource_reference(&blitter->saved_vertex_buffer.buffer, |
vertex_buffers[blitter->vb_slot].buffer); |
memcpy(&blitter->saved_vertex_buffer, &vertex_buffers[blitter->vb_slot], |
sizeof(struct pipe_vertex_buffer)); |
} |
static INLINE void |
util_blitter_save_so_targets(struct blitter_context *blitter, |
unsigned num_targets, |
struct pipe_stream_output_target **targets) |
{ |
unsigned i; |
assert(num_targets <= Elements(blitter->saved_so_targets)); |
blitter->saved_num_so_targets = num_targets; |
for (i = 0; i < num_targets; i++) |
pipe_so_target_reference(&blitter->saved_so_targets[i], |
targets[i]); |
} |
static INLINE void |
util_blitter_save_sample_mask(struct blitter_context *blitter, |
unsigned sample_mask) |
{ |
blitter->is_sample_mask_saved = TRUE; |
blitter->saved_sample_mask = sample_mask; |
} |
static INLINE void |
util_blitter_save_render_condition(struct blitter_context *blitter, |
struct pipe_query *query, |
boolean condition, |
uint mode) |
{ |
blitter->saved_render_cond_query = query; |
blitter->saved_render_cond_mode = mode; |
blitter->saved_render_cond_cond = condition; |
} |
#ifdef __cplusplus |
} |
#endif |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_box.h |
---|
0,0 → 1,80 |
#ifndef UTIL_BOX_INLINES_H |
#define UTIL_BOX_INLINES_H |
#include "pipe/p_state.h" |
static INLINE |
void u_box_1d( unsigned x, |
unsigned w, |
struct pipe_box *box ) |
{ |
box->x = x; |
box->y = 0; |
box->z = 0; |
box->width = w; |
box->height = 1; |
box->depth = 1; |
} |
static INLINE |
void u_box_2d( unsigned x, |
unsigned y, |
unsigned w, |
unsigned h, |
struct pipe_box *box ) |
{ |
box->x = x; |
box->y = y; |
box->z = 0; |
box->width = w; |
box->height = h; |
box->depth = 1; |
} |
static INLINE |
void u_box_origin_2d( unsigned w, |
unsigned h, |
struct pipe_box *box ) |
{ |
box->x = 0; |
box->y = 0; |
box->z = 0; |
box->width = w; |
box->height = h; |
box->depth = 1; |
} |
static INLINE |
void u_box_2d_zslice( unsigned x, |
unsigned y, |
unsigned z, |
unsigned w, |
unsigned h, |
struct pipe_box *box ) |
{ |
box->x = x; |
box->y = y; |
box->z = z; |
box->width = w; |
box->height = h; |
box->depth = 1; |
} |
static INLINE |
void u_box_3d( unsigned x, |
unsigned y, |
unsigned z, |
unsigned w, |
unsigned h, |
unsigned d, |
struct pipe_box *box ) |
{ |
box->x = x; |
box->y = y; |
box->z = z; |
box->width = w; |
box->height = h; |
box->depth = d; |
} |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_cache.c |
---|
0,0 → 1,351 |
/************************************************************************** |
* |
* Copyright 2008 VMware, Inc. |
* 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 VMWARE 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. |
* |
**************************************************************************/ |
/** |
* @file |
* Improved cache implementation. |
* |
* Fixed size array with linear probing on collision and LRU eviction |
* on full. |
* |
* @author Jose Fonseca <jfonseca@vmware.com> |
*/ |
#include "pipe/p_compiler.h" |
#include "util/u_debug.h" |
#include "util/u_math.h" |
#include "util/u_memory.h" |
#include "util/u_cache.h" |
#include "util/u_simple_list.h" |
struct util_cache_entry |
{ |
enum { EMPTY = 0, FILLED, DELETED } state; |
uint32_t hash; |
struct util_cache_entry *next; |
struct util_cache_entry *prev; |
void *key; |
void *value; |
#ifdef DEBUG |
unsigned count; |
#endif |
}; |
struct util_cache |
{ |
/** Hash function */ |
uint32_t (*hash)(const void *key); |
/** Compare two keys */ |
int (*compare)(const void *key1, const void *key2); |
/** Destroy a (key, value) pair */ |
void (*destroy)(void *key, void *value); |
uint32_t size; |
struct util_cache_entry *entries; |
unsigned count; |
struct util_cache_entry lru; |
}; |
static void |
ensure_sanity(const struct util_cache *cache); |
#define CACHE_DEFAULT_ALPHA 2 |
struct util_cache * |
util_cache_create(uint32_t (*hash)(const void *key), |
int (*compare)(const void *key1, const void *key2), |
void (*destroy)(void *key, void *value), |
uint32_t size) |
{ |
struct util_cache *cache; |
cache = CALLOC_STRUCT(util_cache); |
if(!cache) |
return NULL; |
cache->hash = hash; |
cache->compare = compare; |
cache->destroy = destroy; |
make_empty_list(&cache->lru); |
size *= CACHE_DEFAULT_ALPHA; |
cache->size = size; |
cache->entries = CALLOC(size, sizeof(struct util_cache_entry)); |
if(!cache->entries) { |
FREE(cache); |
return NULL; |
} |
ensure_sanity(cache); |
return cache; |
} |
static struct util_cache_entry * |
util_cache_entry_get(struct util_cache *cache, |
uint32_t hash, |
const void *key) |
{ |
struct util_cache_entry *first_unfilled = NULL; |
uint32_t index = hash % cache->size; |
uint32_t probe; |
/* Probe until we find either a matching FILLED entry or an EMPTY |
* slot (which has never been occupied). |
* |
* Deleted or non-matching slots are not indicative of completion |
* as a previous linear probe for the same key could have continued |
* past this point. |
*/ |
for (probe = 0; probe < cache->size; probe++) { |
uint32_t i = (index + probe) % cache->size; |
struct util_cache_entry *current = &cache->entries[i]; |
if (current->state == FILLED) { |
if (current->hash == hash && |
cache->compare(key, current->key) == 0) |
return current; |
} |
else { |
if (!first_unfilled) |
first_unfilled = current; |
if (current->state == EMPTY) |
return first_unfilled; |
} |
} |
return NULL; |
} |
static INLINE void |
util_cache_entry_destroy(struct util_cache *cache, |
struct util_cache_entry *entry) |
{ |
void *key = entry->key; |
void *value = entry->value; |
entry->key = NULL; |
entry->value = NULL; |
if (entry->state == FILLED) { |
remove_from_list(entry); |
cache->count--; |
if(cache->destroy) |
cache->destroy(key, value); |
entry->state = DELETED; |
} |
} |
void |
util_cache_set(struct util_cache *cache, |
void *key, |
void *value) |
{ |
struct util_cache_entry *entry; |
uint32_t hash; |
assert(cache); |
if (!cache) |
return; |
hash = cache->hash(key); |
entry = util_cache_entry_get(cache, hash, key); |
if (!entry) |
entry = cache->lru.prev; |
if (cache->count >= cache->size / CACHE_DEFAULT_ALPHA) |
util_cache_entry_destroy(cache, cache->lru.prev); |
util_cache_entry_destroy(cache, entry); |
#ifdef DEBUG |
++entry->count; |
#endif |
entry->key = key; |
entry->hash = hash; |
entry->value = value; |
entry->state = FILLED; |
insert_at_head(&cache->lru, entry); |
cache->count++; |
ensure_sanity(cache); |
} |
void * |
util_cache_get(struct util_cache *cache, |
const void *key) |
{ |
struct util_cache_entry *entry; |
uint32_t hash; |
assert(cache); |
if (!cache) |
return NULL; |
hash = cache->hash(key); |
entry = util_cache_entry_get(cache, hash, key); |
if (!entry) |
return NULL; |
if (entry->state == FILLED) |
move_to_head(&cache->lru, entry); |
return entry->value; |
} |
void |
util_cache_clear(struct util_cache *cache) |
{ |
uint32_t i; |
assert(cache); |
if (!cache) |
return; |
for(i = 0; i < cache->size; ++i) { |
util_cache_entry_destroy(cache, &cache->entries[i]); |
cache->entries[i].state = EMPTY; |
} |
assert(cache->count == 0); |
assert(is_empty_list(&cache->lru)); |
ensure_sanity(cache); |
} |
void |
util_cache_destroy(struct util_cache *cache) |
{ |
assert(cache); |
if (!cache) |
return; |
#ifdef DEBUG |
if(cache->count >= 20*cache->size) { |
/* Normal approximation of the Poisson distribution */ |
double mean = (double)cache->count/(double)cache->size; |
double stddev = sqrt(mean); |
unsigned i; |
for(i = 0; i < cache->size; ++i) { |
double z = fabs(cache->entries[i].count - mean)/stddev; |
/* This assert should not fail 99.9999998027% of the times, unless |
* the hash function is a poor one */ |
assert(z <= 6.0); |
} |
} |
#endif |
util_cache_clear(cache); |
FREE(cache->entries); |
FREE(cache); |
} |
void |
util_cache_remove(struct util_cache *cache, |
const void *key) |
{ |
struct util_cache_entry *entry; |
uint32_t hash; |
assert(cache); |
if (!cache) |
return; |
hash = cache->hash(key); |
entry = util_cache_entry_get(cache, hash, key); |
if (!entry) |
return; |
if (entry->state == FILLED) |
util_cache_entry_destroy(cache, entry); |
ensure_sanity(cache); |
} |
static void |
ensure_sanity(const struct util_cache *cache) |
{ |
#ifdef DEBUG |
unsigned i, cnt = 0; |
assert(cache); |
for (i = 0; i < cache->size; i++) { |
struct util_cache_entry *header = &cache->entries[i]; |
assert(header); |
assert(header->state == FILLED || |
header->state == EMPTY || |
header->state == DELETED); |
if (header->state == FILLED) { |
cnt++; |
assert(header->hash == cache->hash(header->key)); |
} |
} |
assert(cnt == cache->count); |
assert(cache->size >= cnt); |
if (cache->count == 0) { |
assert (is_empty_list(&cache->lru)); |
} |
else { |
struct util_cache_entry *header = cache->lru.next; |
assert (header); |
assert (!is_empty_list(&cache->lru)); |
for (i = 0; i < cache->count; i++) |
header = header->next; |
assert(header == &cache->lru); |
} |
#endif |
(void)cache; |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_cache.h |
---|
0,0 → 1,91 |
/************************************************************************** |
* |
* Copyright 2008 VMware, Inc. |
* 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 VMWARE 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. |
* |
**************************************************************************/ |
/** |
* @file |
* Simple cache. |
* |
* @author Jose Fonseca <jfonseca@vmware.com> |
*/ |
#ifndef U_CACHE_H_ |
#define U_CACHE_H_ |
#include "pipe/p_compiler.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* Least Recently Used (LRU) cache. |
*/ |
struct util_cache; |
/** |
* Create a cache. |
* |
* @param hash hash function |
* @param compare should return 0 for two equal keys |
* @param destroy destruction callback (optional) |
* @param size maximum number of entries |
*/ |
struct util_cache * |
util_cache_create(uint32_t (*hash)(const void *key), |
int (*compare)(const void *key1, const void *key2), |
void (*destroy)(void *key, void *value), |
uint32_t size); |
void |
util_cache_set(struct util_cache *cache, |
void *key, |
void *value); |
void * |
util_cache_get(struct util_cache *cache, |
const void *key); |
void |
util_cache_clear(struct util_cache *cache); |
void |
util_cache_destroy(struct util_cache *cache); |
void |
util_cache_remove(struct util_cache *cache, |
const void *key); |
#ifdef __cplusplus |
} |
#endif |
#endif /* U_CACHE_H_ */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_caps.c |
---|
0,0 → 1,269 |
/************************************************************************** |
* |
* Copyright 2010 Vmware, Inc. |
* 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 VMWARE 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 "pipe/p_screen.h" |
#include "util/u_format.h" |
#include "util/u_debug.h" |
#include "u_caps.h" |
/** |
* Iterates over a list of caps checks as defined in u_caps.h. Should |
* all checks pass returns TRUE and out is set to the last element of |
* the list (TERMINATE). Should any check fail returns FALSE and set |
* out to the index of the start of the first failing check. |
*/ |
boolean |
util_check_caps_out(struct pipe_screen *screen, const unsigned *list, int *out) |
{ |
int i, tmpi; |
float tmpf; |
for (i = 0; list[i];) { |
switch(list[i++]) { |
case UTIL_CAPS_CHECK_CAP: |
if (!screen->get_param(screen, list[i++])) { |
*out = i - 2; |
return FALSE; |
} |
break; |
case UTIL_CAPS_CHECK_INT: |
tmpi = screen->get_param(screen, list[i++]); |
if (tmpi < (int)list[i++]) { |
*out = i - 3; |
return FALSE; |
} |
break; |
case UTIL_CAPS_CHECK_FLOAT: |
tmpf = screen->get_paramf(screen, list[i++]); |
if (tmpf < (float)list[i++]) { |
*out = i - 3; |
return FALSE; |
} |
break; |
case UTIL_CAPS_CHECK_FORMAT: |
if (!screen->is_format_supported(screen, |
list[i++], |
PIPE_TEXTURE_2D, |
0, |
PIPE_BIND_SAMPLER_VIEW)) { |
*out = i - 2; |
return FALSE; |
} |
break; |
case UTIL_CAPS_CHECK_SHADER: |
tmpi = screen->get_shader_param(screen, list[i] >> 24, list[i] & ((1 << 24) - 1)); |
++i; |
if (tmpi < (int)list[i++]) { |
*out = i - 3; |
return FALSE; |
} |
break; |
case UTIL_CAPS_CHECK_UNIMPLEMENTED: |
*out = i - 1; |
return FALSE; |
default: |
assert(!"Unsupported check"); |
return FALSE; |
} |
} |
*out = i; |
return TRUE; |
} |
/** |
* Iterates over a list of caps checks as defined in u_caps.h. |
* Returns TRUE if all caps checks pass returns FALSE otherwise. |
*/ |
boolean |
util_check_caps(struct pipe_screen *screen, const unsigned *list) |
{ |
int out; |
return util_check_caps_out(screen, list, &out); |
} |
/* |
* Below follows some demo lists. |
* |
* None of these lists are exhausting lists of what is |
* actually needed to support said API and more here for |
* as example on how to uses the above functions. Especially |
* for DX10 and DX11 where Gallium is missing features. |
*/ |
/* DX 9_1 */ |
static unsigned caps_dx_9_1[] = { |
UTIL_CHECK_INT(MAX_RENDER_TARGETS, 1), |
UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 12), /* 2048 */ |
UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 9), /* 256 */ |
UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 10), /* 512 */ |
UTIL_CHECK_FLOAT(MAX_TEXTURE_ANISOTROPY, 2), |
UTIL_CHECK_TERMINATE |
}; |
/* DX 9_2 */ |
static unsigned caps_dx_9_2[] = { |
UTIL_CHECK_CAP(OCCLUSION_QUERY), |
UTIL_CHECK_CAP(BLEND_EQUATION_SEPARATE), |
UTIL_CHECK_INT(MAX_RENDER_TARGETS, 1), |
UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 12), /* 2048 */ |
UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 9), /* 256 */ |
UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 10), /* 512 */ |
UTIL_CHECK_FLOAT(MAX_TEXTURE_ANISOTROPY, 16), |
UTIL_CHECK_TERMINATE |
}; |
/* DX 9_3 */ |
static unsigned caps_dx_9_3[] = { |
UTIL_CHECK_CAP(SM3), |
//UTIL_CHECK_CAP(INSTANCING), |
UTIL_CHECK_CAP(OCCLUSION_QUERY), |
UTIL_CHECK_INT(MAX_RENDER_TARGETS, 4), |
UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 13), /* 4096 */ |
UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 9), /* 256 */ |
UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 10), /* 512 */ |
UTIL_CHECK_FLOAT(MAX_TEXTURE_ANISOTROPY, 16), |
UTIL_CHECK_TERMINATE |
}; |
/* DX 10 */ |
static unsigned caps_dx_10[] = { |
UTIL_CHECK_CAP(SM3), |
//UTIL_CHECK_CAP(INSTANCING), |
UTIL_CHECK_CAP(OCCLUSION_QUERY), |
UTIL_CHECK_INT(MAX_RENDER_TARGETS, 8), |
UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 14), /* 8192 */ |
UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 12), /* 2048 */ |
UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 14), /* 8192 */ |
UTIL_CHECK_FLOAT(MAX_TEXTURE_ANISOTROPY, 16), |
UTIL_CHECK_UNIMPLEMENTED, /* XXX Unimplemented features in Gallium */ |
UTIL_CHECK_TERMINATE |
}; |
/* DX11 */ |
static unsigned caps_dx_11[] = { |
UTIL_CHECK_CAP(SM3), |
//UTIL_CHECK_CAP(INSTANCING), |
UTIL_CHECK_CAP(OCCLUSION_QUERY), |
UTIL_CHECK_INT(MAX_RENDER_TARGETS, 8), |
UTIL_CHECK_INT(MAX_TEXTURE_2D_LEVELS, 14), /* 16384 */ |
UTIL_CHECK_INT(MAX_TEXTURE_3D_LEVELS, 12), /* 2048 */ |
UTIL_CHECK_INT(MAX_TEXTURE_CUBE_LEVELS, 14), /* 16384 */ |
UTIL_CHECK_FLOAT(MAX_TEXTURE_ANISOTROPY, 16), |
UTIL_CHECK_FORMAT(B8G8R8A8_UNORM), |
UTIL_CHECK_UNIMPLEMENTED, /* XXX Unimplemented features in Gallium */ |
UTIL_CHECK_TERMINATE |
}; |
/* OpenGL 2.1 */ |
static unsigned caps_opengl_2_1[] = { |
UTIL_CHECK_CAP(OCCLUSION_QUERY), |
UTIL_CHECK_CAP(TWO_SIDED_STENCIL), |
UTIL_CHECK_CAP(BLEND_EQUATION_SEPARATE), |
UTIL_CHECK_INT(MAX_RENDER_TARGETS, 2), |
UTIL_CHECK_TERMINATE |
}; |
/* OpenGL 3.0 */ |
/* UTIL_CHECK_INT(MAX_RENDER_TARGETS, 8), */ |
/* Shader Model 3 */ |
static unsigned caps_sm3[] = { |
UTIL_CHECK_SHADER(FRAGMENT, MAX_INSTRUCTIONS, 512), |
UTIL_CHECK_SHADER(FRAGMENT, MAX_INPUTS, 10), |
UTIL_CHECK_SHADER(FRAGMENT, MAX_TEMPS, 32), |
UTIL_CHECK_SHADER(FRAGMENT, MAX_ADDRS, 1), |
UTIL_CHECK_SHADER(FRAGMENT, MAX_CONSTS, 224), |
UTIL_CHECK_SHADER(VERTEX, MAX_INSTRUCTIONS, 512), |
UTIL_CHECK_SHADER(VERTEX, MAX_INPUTS, 16), |
UTIL_CHECK_SHADER(VERTEX, MAX_TEMPS, 32), |
UTIL_CHECK_SHADER(VERTEX, MAX_ADDRS, 2), |
UTIL_CHECK_SHADER(VERTEX, MAX_CONSTS, 256), |
UTIL_CHECK_TERMINATE |
}; |
/** |
* Demo function which checks against theoretical caps needed for different APIs. |
*/ |
void util_caps_demo_print(struct pipe_screen *screen) |
{ |
struct { |
char* name; |
unsigned *list; |
} list[] = { |
{"DX 9.1", caps_dx_9_1}, |
{"DX 9.2", caps_dx_9_2}, |
{"DX 9.3", caps_dx_9_3}, |
{"DX 10", caps_dx_10}, |
{"DX 11", caps_dx_11}, |
{"OpenGL 2.1", caps_opengl_2_1}, |
/* {"OpenGL 3.0", caps_opengl_3_0},*/ |
{"SM3", caps_sm3}, |
{NULL, NULL} |
}; |
int i, out = 0; |
for (i = 0; list[i].name; i++) { |
if (util_check_caps_out(screen, list[i].list, &out)) { |
debug_printf("%s: %s yes\n", __FUNCTION__, list[i].name); |
continue; |
} |
switch (list[i].list[out]) { |
case UTIL_CAPS_CHECK_CAP: |
debug_printf("%s: %s no (cap %u not supported)\n", __FUNCTION__, |
list[i].name, |
list[i].list[out + 1]); |
break; |
case UTIL_CAPS_CHECK_INT: |
debug_printf("%s: %s no (cap %u less then %u)\n", __FUNCTION__, |
list[i].name, |
list[i].list[out + 1], |
list[i].list[out + 2]); |
break; |
case UTIL_CAPS_CHECK_FLOAT: |
debug_printf("%s: %s no (cap %u less then %f)\n", __FUNCTION__, |
list[i].name, |
list[i].list[out + 1], |
(double)(int)list[i].list[out + 2]); |
break; |
case UTIL_CAPS_CHECK_FORMAT: |
debug_printf("%s: %s no (format %s not supported)\n", __FUNCTION__, |
list[i].name, |
util_format_name(list[i].list[out + 1]) + 12); |
break; |
case UTIL_CAPS_CHECK_UNIMPLEMENTED: |
debug_printf("%s: %s no (not implemented in gallium or state tracker)\n", |
__FUNCTION__, list[i].name); |
break; |
default: |
assert(!"Unsupported check"); |
} |
} |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_caps.h |
---|
0,0 → 1,71 |
/************************************************************************** |
* |
* Copyright 2010 Vmware, Inc. |
* 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 VMWARE 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_CAPS_H |
#define U_CAPS_H |
#include "pipe/p_compiler.h" |
struct pipe_screen; |
enum u_caps_check_enum { |
UTIL_CAPS_CHECK_TERMINATE = 0, |
UTIL_CAPS_CHECK_CAP, |
UTIL_CAPS_CHECK_INT, |
UTIL_CAPS_CHECK_FLOAT, |
UTIL_CAPS_CHECK_FORMAT, |
UTIL_CAPS_CHECK_SHADER, |
UTIL_CAPS_CHECK_UNIMPLEMENTED, |
}; |
#define UTIL_CHECK_CAP(cap) \ |
UTIL_CAPS_CHECK_CAP, PIPE_CAP_##cap |
#define UTIL_CHECK_INT(cap, higher) \ |
UTIL_CAPS_CHECK_INT, PIPE_CAP_##cap, (unsigned)(higher) |
/* Floats currently lose precision */ |
#define UTIL_CHECK_FLOAT(cap, higher) \ |
UTIL_CAPS_CHECK_FLOAT, PIPE_CAPF_##cap, (unsigned)(int)(higher) |
#define UTIL_CHECK_FORMAT(format) \ |
UTIL_CAPS_CHECK_FORMAT, PIPE_FORMAT_##format |
#define UTIL_CHECK_SHADER(shader, cap, higher) \ |
UTIL_CAPS_CHECK_SHADER, (PIPE_SHADER_##shader << 24) | PIPE_SHADER_CAP_##cap, (unsigned)(higher) |
#define UTIL_CHECK_UNIMPLEMENTED \ |
UTIL_CAPS_CHECK_UNIMPLEMENTED |
#define UTIL_CHECK_TERMINATE \ |
UTIL_CAPS_CHECK_TERMINATE |
boolean util_check_caps(struct pipe_screen *screen, const unsigned *list); |
boolean util_check_caps_out(struct pipe_screen *screen, const unsigned *list, int *out); |
void util_caps_demo_print(struct pipe_screen *screen); |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_clear.h |
---|
0,0 → 1,59 |
/************************************************************************** |
* |
* Copyright 2009 VMware, Inc. 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 TUNGSTEN GRAPHICS 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. |
* |
**************************************************************************/ |
/* Authors: |
* Michel Dänzer |
*/ |
#include "pipe/p_context.h" |
#include "pipe/p_state.h" |
/** |
* Clear the given buffers to the specified values. |
* No masking, no scissor (clear entire buffer). |
*/ |
static INLINE void |
util_clear(struct pipe_context *pipe, |
struct pipe_framebuffer_state *framebuffer, unsigned buffers, |
const union pipe_color_union *color, double depth, unsigned stencil) |
{ |
if (buffers & PIPE_CLEAR_COLOR) { |
unsigned i; |
for (i = 0; i < framebuffer->nr_cbufs; i++) { |
struct pipe_surface *ps = framebuffer->cbufs[i]; |
pipe->clear_render_target(pipe, ps, color, 0, 0, ps->width, ps->height); |
} |
} |
if (buffers & PIPE_CLEAR_DEPTHSTENCIL) { |
struct pipe_surface *ps = framebuffer->zsbuf; |
pipe->clear_depth_stencil(pipe, ps, buffers & PIPE_CLEAR_DEPTHSTENCIL, |
depth, stencil, |
0, 0, ps->width, ps->height); |
} |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_cpu_detect.c |
---|
0,0 → 1,355 |
/************************************************************************** |
* |
* Copyright 2008 Dennis Smit |
* 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 |
* on 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, COPYRIGHT HOLDERS, AND/OR THEIR 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. |
* |
**************************************************************************/ |
/** |
* @file |
* CPU feature detection. |
* |
* @author Dennis Smit |
* @author Based on the work of Eric Anholt <anholt@FreeBSD.org> |
*/ |
#include "pipe/p_config.h" |
#include "u_debug.h" |
#include "u_cpu_detect.h" |
#if defined(PIPE_ARCH_PPC) |
#if defined(PIPE_OS_APPLE) |
#include <sys/sysctl.h> |
#else |
#include <signal.h> |
#include <setjmp.h> |
#endif |
#endif |
#if defined(PIPE_OS_NETBSD) || defined(PIPE_OS_OPENBSD) |
#include <sys/param.h> |
#include <sys/sysctl.h> |
#include <machine/cpu.h> |
#endif |
#if defined(PIPE_OS_FREEBSD) |
#include <sys/types.h> |
#include <sys/sysctl.h> |
#endif |
#if defined(PIPE_OS_LINUX) |
#include <signal.h> |
#endif |
#ifdef PIPE_OS_UNIX |
#include <unistd.h> |
#endif |
#if defined(PIPE_OS_WINDOWS) |
#include <windows.h> |
#if defined(MSVC) |
#include <intrin.h> |
#endif |
#endif |
#ifdef DEBUG |
DEBUG_GET_ONCE_BOOL_OPTION(dump_cpu, "GALLIUM_DUMP_CPU", FALSE) |
#endif |
struct util_cpu_caps util_cpu_caps; |
#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) |
static int has_cpuid(void); |
#endif |
#if defined(PIPE_ARCH_PPC) && !defined(PIPE_OS_APPLE) |
static jmp_buf __lv_powerpc_jmpbuf; |
static volatile sig_atomic_t __lv_powerpc_canjump = 0; |
static void |
sigill_handler(int sig) |
{ |
if (!__lv_powerpc_canjump) { |
signal (sig, SIG_DFL); |
raise (sig); |
} |
__lv_powerpc_canjump = 0; |
longjmp(__lv_powerpc_jmpbuf, 1); |
} |
#endif |
#if defined(PIPE_ARCH_PPC) |
static void |
check_os_altivec_support(void) |
{ |
#if defined(PIPE_OS_APPLE) |
int sels[2] = {CTL_HW, HW_VECTORUNIT}; |
int has_vu = 0; |
int len = sizeof (has_vu); |
int err; |
err = sysctl(sels, 2, &has_vu, &len, NULL, 0); |
if (err == 0) { |
if (has_vu != 0) { |
util_cpu_caps.has_altivec = 1; |
} |
} |
#else /* !PIPE_OS_APPLE */ |
/* not on Apple/Darwin, do it the brute-force way */ |
/* this is borrowed from the libmpeg2 library */ |
signal(SIGILL, sigill_handler); |
if (setjmp(__lv_powerpc_jmpbuf)) { |
signal(SIGILL, SIG_DFL); |
} else { |
__lv_powerpc_canjump = 1; |
__asm __volatile |
("mtspr 256, %0\n\t" |
"vand %%v0, %%v0, %%v0" |
: |
: "r" (-1)); |
signal(SIGILL, SIG_DFL); |
util_cpu_caps.has_altivec = 1; |
} |
#endif /* !PIPE_OS_APPLE */ |
} |
#endif /* PIPE_ARCH_PPC */ |
#if defined(PIPE_ARCH_X86) || defined (PIPE_ARCH_X86_64) |
static int has_cpuid(void) |
{ |
#if defined(PIPE_ARCH_X86) |
#if defined(PIPE_OS_GCC) |
int a, c; |
__asm __volatile |
("pushf\n" |
"popl %0\n" |
"movl %0, %1\n" |
"xorl $0x200000, %0\n" |
"push %0\n" |
"popf\n" |
"pushf\n" |
"popl %0\n" |
: "=a" (a), "=c" (c) |
: |
: "cc"); |
return a != c; |
#else |
/* FIXME */ |
return 1; |
#endif |
#elif defined(PIPE_ARCH_X86_64) |
return 1; |
#else |
return 0; |
#endif |
} |
/** |
* @sa cpuid.h included in gcc-4.3 onwards. |
* @sa http://msdn.microsoft.com/en-us/library/hskdteyh.aspx |
*/ |
static INLINE void |
cpuid(uint32_t ax, uint32_t *p) |
{ |
#if (defined(PIPE_CC_GCC) || defined(PIPE_CC_SUNPRO)) && defined(PIPE_ARCH_X86) |
__asm __volatile ( |
"xchgl %%ebx, %1\n\t" |
"cpuid\n\t" |
"xchgl %%ebx, %1" |
: "=a" (p[0]), |
"=S" (p[1]), |
"=c" (p[2]), |
"=d" (p[3]) |
: "0" (ax) |
); |
#elif (defined(PIPE_CC_GCC) || defined(PIPE_CC_SUNPRO)) && defined(PIPE_ARCH_X86_64) |
__asm __volatile ( |
"cpuid\n\t" |
: "=a" (p[0]), |
"=b" (p[1]), |
"=c" (p[2]), |
"=d" (p[3]) |
: "0" (ax) |
); |
#elif defined(PIPE_CC_MSVC) |
__cpuid(p, ax); |
#else |
p[0] = 0; |
p[1] = 0; |
p[2] = 0; |
p[3] = 0; |
#endif |
} |
#endif /* X86 or X86_64 */ |
void |
util_cpu_detect(void) |
{ |
static boolean util_cpu_detect_initialized = FALSE; |
if(util_cpu_detect_initialized) |
return; |
memset(&util_cpu_caps, 0, sizeof util_cpu_caps); |
/* Count the number of CPUs in system */ |
#if defined(PIPE_OS_WINDOWS) |
{ |
SYSTEM_INFO system_info; |
GetSystemInfo(&system_info); |
util_cpu_caps.nr_cpus = system_info.dwNumberOfProcessors; |
} |
#elif defined(PIPE_OS_UNIX) && defined(_SC_NPROCESSORS_ONLN) |
util_cpu_caps.nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); |
if (util_cpu_caps.nr_cpus == -1) |
util_cpu_caps.nr_cpus = 1; |
#elif defined(PIPE_OS_BSD) |
{ |
int mib[2], ncpu; |
int len; |
mib[0] = CTL_HW; |
mib[1] = HW_NCPU; |
len = sizeof (ncpu); |
sysctl(mib, 2, &ncpu, &len, NULL, 0); |
util_cpu_caps.nr_cpus = ncpu; |
} |
#else |
util_cpu_caps.nr_cpus = 1; |
#endif |
/* Make the fallback cacheline size nonzero so that it can be |
* safely passed to align(). |
*/ |
util_cpu_caps.cacheline = sizeof(void *); |
#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64) |
if (has_cpuid()) { |
uint32_t regs[4]; |
uint32_t regs2[4]; |
util_cpu_caps.cacheline = 32; |
/* Get max cpuid level */ |
cpuid(0x00000000, regs); |
if (regs[0] >= 0x00000001) { |
unsigned int cacheline; |
cpuid (0x00000001, regs2); |
util_cpu_caps.x86_cpu_type = (regs2[0] >> 8) & 0xf; |
if (util_cpu_caps.x86_cpu_type == 0xf) |
util_cpu_caps.x86_cpu_type = 8 + ((regs2[0] >> 20) & 255); /* use extended family (P4, IA64) */ |
/* general feature flags */ |
util_cpu_caps.has_tsc = (regs2[3] >> 4) & 1; /* 0x0000010 */ |
util_cpu_caps.has_mmx = (regs2[3] >> 23) & 1; /* 0x0800000 */ |
util_cpu_caps.has_sse = (regs2[3] >> 25) & 1; /* 0x2000000 */ |
util_cpu_caps.has_sse2 = (regs2[3] >> 26) & 1; /* 0x4000000 */ |
util_cpu_caps.has_sse3 = (regs2[2] >> 0) & 1; /* 0x0000001 */ |
util_cpu_caps.has_ssse3 = (regs2[2] >> 9) & 1; /* 0x0000020 */ |
util_cpu_caps.has_sse4_1 = (regs2[2] >> 19) & 1; |
util_cpu_caps.has_sse4_2 = (regs2[2] >> 20) & 1; |
util_cpu_caps.has_popcnt = (regs2[2] >> 23) & 1; |
util_cpu_caps.has_avx = (regs2[2] >> 28) & 1; |
util_cpu_caps.has_f16c = (regs2[2] >> 29) & 1; |
util_cpu_caps.has_mmx2 = util_cpu_caps.has_sse; /* SSE cpus supports mmxext too */ |
cacheline = ((regs2[1] >> 8) & 0xFF) * 8; |
if (cacheline > 0) |
util_cpu_caps.cacheline = cacheline; |
} |
if (regs[1] == 0x756e6547 && regs[2] == 0x6c65746e && regs[3] == 0x49656e69) { |
/* GenuineIntel */ |
util_cpu_caps.has_intel = 1; |
} |
cpuid(0x80000000, regs); |
if (regs[0] >= 0x80000001) { |
cpuid(0x80000001, regs2); |
util_cpu_caps.has_mmx |= (regs2[3] >> 23) & 1; |
util_cpu_caps.has_mmx2 |= (regs2[3] >> 22) & 1; |
util_cpu_caps.has_3dnow = (regs2[3] >> 31) & 1; |
util_cpu_caps.has_3dnow_ext = (regs2[3] >> 30) & 1; |
} |
if (regs[0] >= 0x80000006) { |
cpuid(0x80000006, regs2); |
util_cpu_caps.cacheline = regs2[2] & 0xFF; |
} |
if (!util_cpu_caps.has_sse) { |
util_cpu_caps.has_sse2 = 0; |
util_cpu_caps.has_sse3 = 0; |
util_cpu_caps.has_ssse3 = 0; |
util_cpu_caps.has_sse4_1 = 0; |
} |
} |
#endif /* PIPE_ARCH_X86 || PIPE_ARCH_X86_64 */ |
#if defined(PIPE_ARCH_PPC) |
check_os_altivec_support(); |
#endif /* PIPE_ARCH_PPC */ |
#ifdef DEBUG |
if (debug_get_option_dump_cpu()) { |
debug_printf("util_cpu_caps.nr_cpus = %u\n", util_cpu_caps.nr_cpus); |
debug_printf("util_cpu_caps.x86_cpu_type = %u\n", util_cpu_caps.x86_cpu_type); |
debug_printf("util_cpu_caps.cacheline = %u\n", util_cpu_caps.cacheline); |
debug_printf("util_cpu_caps.has_tsc = %u\n", util_cpu_caps.has_tsc); |
debug_printf("util_cpu_caps.has_mmx = %u\n", util_cpu_caps.has_mmx); |
debug_printf("util_cpu_caps.has_mmx2 = %u\n", util_cpu_caps.has_mmx2); |
debug_printf("util_cpu_caps.has_sse = %u\n", util_cpu_caps.has_sse); |
debug_printf("util_cpu_caps.has_sse2 = %u\n", util_cpu_caps.has_sse2); |
debug_printf("util_cpu_caps.has_sse3 = %u\n", util_cpu_caps.has_sse3); |
debug_printf("util_cpu_caps.has_ssse3 = %u\n", util_cpu_caps.has_ssse3); |
debug_printf("util_cpu_caps.has_sse4_1 = %u\n", util_cpu_caps.has_sse4_1); |
debug_printf("util_cpu_caps.has_sse4_2 = %u\n", util_cpu_caps.has_sse4_2); |
debug_printf("util_cpu_caps.has_avx = %u\n", util_cpu_caps.has_avx); |
debug_printf("util_cpu_caps.has_3dnow = %u\n", util_cpu_caps.has_3dnow); |
debug_printf("util_cpu_caps.has_3dnow_ext = %u\n", util_cpu_caps.has_3dnow_ext); |
debug_printf("util_cpu_caps.has_altivec = %u\n", util_cpu_caps.has_altivec); |
} |
#endif |
util_cpu_detect_initialized = TRUE; |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_cpu_detect.h |
---|
0,0 → 1,84 |
/************************************************************************** |
* |
* Copyright 2008 Dennis Smit |
* 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 |
* on 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, COPYRIGHT HOLDERS, AND/OR THEIR 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. |
* |
***************************************************************************/ |
/** |
* @file |
* CPU feature detection. |
* |
* @author Dennis Smit |
* @author Based on the work of Eric Anholt <anholt@FreeBSD.org> |
*/ |
#ifndef _UTIL_CPU_DETECT_H |
#define _UTIL_CPU_DETECT_H |
#include "pipe/p_compiler.h" |
#include "pipe/p_config.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
struct util_cpu_caps { |
unsigned nr_cpus; |
/* Feature flags */ |
int x86_cpu_type; |
unsigned cacheline; |
unsigned has_intel:1; |
unsigned has_tsc:1; |
unsigned has_mmx:1; |
unsigned has_mmx2:1; |
unsigned has_sse:1; |
unsigned has_sse2:1; |
unsigned has_sse3:1; |
unsigned has_ssse3:1; |
unsigned has_sse4_1:1; |
unsigned has_sse4_2:1; |
unsigned has_popcnt:1; |
unsigned has_avx:1; |
unsigned has_f16c:1; |
unsigned has_3dnow:1; |
unsigned has_3dnow_ext:1; |
unsigned has_altivec:1; |
}; |
extern struct util_cpu_caps |
util_cpu_caps; |
void util_cpu_detect(void); |
#ifdef __cplusplus |
} |
#endif |
#endif /* _UTIL_CPU_DETECT_H */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_debug.c |
---|
0,0 → 1,730 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* Copyright (c) 2008 VMware, Inc. |
* 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 TUNGSTEN GRAPHICS 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 "pipe/p_config.h" |
#include "pipe/p_compiler.h" |
#include "util/u_debug.h" |
#include "pipe/p_format.h" |
#include "pipe/p_state.h" |
#include "util/u_inlines.h" |
#include "util/u_format.h" |
#include "util/u_memory.h" |
#include "util/u_string.h" |
#include "util/u_math.h" |
#include "util/u_tile.h" |
#include "util/u_prim.h" |
#include "util/u_surface.h" |
#include <stdio.h> |
#include <limits.h> /* CHAR_BIT */ |
#include <ctype.h> /* isalnum */ |
void _debug_vprintf(const char *format, va_list ap) |
{ |
static char buf[4096] = {'\0'}; |
#if defined(PIPE_OS_WINDOWS) || defined(PIPE_SUBSYSTEM_EMBEDDED) |
/* We buffer until we find a newline. */ |
size_t len = strlen(buf); |
int ret = util_vsnprintf(buf + len, sizeof(buf) - len, format, ap); |
if(ret > (int)(sizeof(buf) - len - 1) || util_strchr(buf + len, '\n')) { |
os_log_message(buf); |
buf[0] = '\0'; |
} |
#else |
util_vsnprintf(buf, sizeof(buf), format, ap); |
os_log_message(buf); |
#endif |
} |
#ifdef DEBUG |
void debug_print_blob( const char *name, |
const void *blob, |
unsigned size ) |
{ |
const unsigned *ublob = (const unsigned *)blob; |
unsigned i; |
debug_printf("%s (%d dwords%s)\n", name, size/4, |
size%4 ? "... plus a few bytes" : ""); |
for (i = 0; i < size/4; i++) { |
debug_printf("%d:\t%08x\n", i, ublob[i]); |
} |
} |
#endif |
static boolean |
debug_get_option_should_print(void) |
{ |
static boolean first = TRUE; |
static boolean value = FALSE; |
if (!first) |
return value; |
/* Oh hey this will call into this function, |
* but its cool since we set first to false |
*/ |
first = FALSE; |
value = debug_get_bool_option("GALLIUM_PRINT_OPTIONS", FALSE); |
/* XXX should we print this option? Currently it wont */ |
return value; |
} |
const char * |
debug_get_option(const char *name, const char *dfault) |
{ |
const char *result; |
result = os_get_option(name); |
if(!result) |
result = dfault; |
if (debug_get_option_should_print()) |
debug_printf("%s: %s = %s\n", __FUNCTION__, name, result ? result : "(null)"); |
return result; |
} |
boolean |
debug_get_bool_option(const char *name, boolean dfault) |
{ |
const char *str = os_get_option(name); |
boolean result; |
if(str == NULL) |
result = dfault; |
else if(!util_strcmp(str, "n")) |
result = FALSE; |
else if(!util_strcmp(str, "no")) |
result = FALSE; |
else if(!util_strcmp(str, "0")) |
result = FALSE; |
else if(!util_strcmp(str, "f")) |
result = FALSE; |
else if(!util_strcmp(str, "F")) |
result = FALSE; |
else if(!util_strcmp(str, "false")) |
result = FALSE; |
else if(!util_strcmp(str, "FALSE")) |
result = FALSE; |
else |
result = TRUE; |
if (debug_get_option_should_print()) |
debug_printf("%s: %s = %s\n", __FUNCTION__, name, result ? "TRUE" : "FALSE"); |
return result; |
} |
long |
debug_get_num_option(const char *name, long dfault) |
{ |
long result; |
const char *str; |
str = os_get_option(name); |
if(!str) |
result = dfault; |
else { |
long sign; |
char c; |
c = *str++; |
if(c == '-') { |
sign = -1; |
c = *str++; |
} |
else { |
sign = 1; |
} |
result = 0; |
while('0' <= c && c <= '9') { |
result = result*10 + (c - '0'); |
c = *str++; |
} |
result *= sign; |
} |
if (debug_get_option_should_print()) |
debug_printf("%s: %s = %li\n", __FUNCTION__, name, result); |
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) || *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, |
const struct debug_named_value *flags, |
unsigned long dfault) |
{ |
unsigned long result; |
const char *str; |
const struct debug_named_value *orig = flags; |
unsigned namealign = 0; |
str = os_get_option(name); |
if(!str) |
result = dfault; |
else if (!util_strcmp(str, "help")) { |
result = dfault; |
_debug_printf("%s: help for %s:\n", __FUNCTION__, name); |
for (; flags->name; ++flags) |
namealign = MAX2(namealign, strlen(flags->name)); |
for (flags = orig; flags->name; ++flags) |
_debug_printf("| %*s [0x%0*lx]%s%s\n", namealign, flags->name, |
(int)sizeof(unsigned long)*CHAR_BIT/4, flags->value, |
flags->desc ? " " : "", flags->desc ? flags->desc : ""); |
} |
else { |
result = 0; |
while( flags->name ) { |
if (str_has_option(str, flags->name)) |
result |= flags->value; |
++flags; |
} |
} |
if (debug_get_option_should_print()) { |
if (str) { |
debug_printf("%s: %s = 0x%lx (%s)\n", __FUNCTION__, name, result, str); |
} else { |
debug_printf("%s: %s = 0x%lx\n", __FUNCTION__, name, result); |
} |
} |
return result; |
} |
void _debug_assert_fail(const char *expr, |
const char *file, |
unsigned line, |
const char *function) |
{ |
_debug_printf("%s:%u:%s: Assertion `%s' failed.\n", file, line, function, expr); |
if (debug_get_bool_option("GALLIUM_ABORT_ON_ASSERT", TRUE)) |
os_abort(); |
else |
_debug_printf("continuing...\n"); |
} |
const char * |
debug_dump_enum(const struct debug_named_value *names, |
unsigned long value) |
{ |
static char rest[64]; |
while(names->name) { |
if(names->value == value) |
return names->name; |
++names; |
} |
util_snprintf(rest, sizeof(rest), "0x%08lx", value); |
return rest; |
} |
const char * |
debug_dump_enum_noprefix(const struct debug_named_value *names, |
const char *prefix, |
unsigned long value) |
{ |
static char rest[64]; |
while(names->name) { |
if(names->value == value) { |
const char *name = names->name; |
while (*name == *prefix) { |
name++; |
prefix++; |
} |
return name; |
} |
++names; |
} |
util_snprintf(rest, sizeof(rest), "0x%08lx", value); |
return rest; |
} |
const char * |
debug_dump_flags(const struct debug_named_value *names, |
unsigned long value) |
{ |
static char output[4096]; |
static char rest[256]; |
int first = 1; |
output[0] = '\0'; |
while(names->name) { |
if((names->value & value) == names->value) { |
if (!first) |
util_strncat(output, "|", sizeof(output)); |
else |
first = 0; |
util_strncat(output, names->name, sizeof(output) - 1); |
output[sizeof(output) - 1] = '\0'; |
value &= ~names->value; |
} |
++names; |
} |
if (value) { |
if (!first) |
util_strncat(output, "|", sizeof(output)); |
else |
first = 0; |
util_snprintf(rest, sizeof(rest), "0x%08lx", value); |
util_strncat(output, rest, sizeof(output) - 1); |
output[sizeof(output) - 1] = '\0'; |
} |
if(first) |
return "0"; |
return output; |
} |
#ifdef DEBUG |
void debug_print_format(const char *msg, unsigned fmt ) |
{ |
debug_printf("%s: %s\n", msg, util_format_name(fmt)); |
} |
#endif |
static const struct debug_named_value pipe_prim_names[] = { |
#ifdef DEBUG |
DEBUG_NAMED_VALUE(PIPE_PRIM_POINTS), |
DEBUG_NAMED_VALUE(PIPE_PRIM_LINES), |
DEBUG_NAMED_VALUE(PIPE_PRIM_LINE_LOOP), |
DEBUG_NAMED_VALUE(PIPE_PRIM_LINE_STRIP), |
DEBUG_NAMED_VALUE(PIPE_PRIM_TRIANGLES), |
DEBUG_NAMED_VALUE(PIPE_PRIM_TRIANGLE_STRIP), |
DEBUG_NAMED_VALUE(PIPE_PRIM_TRIANGLE_FAN), |
DEBUG_NAMED_VALUE(PIPE_PRIM_QUADS), |
DEBUG_NAMED_VALUE(PIPE_PRIM_QUAD_STRIP), |
DEBUG_NAMED_VALUE(PIPE_PRIM_POLYGON), |
DEBUG_NAMED_VALUE(PIPE_PRIM_LINES_ADJACENCY), |
DEBUG_NAMED_VALUE(PIPE_PRIM_LINE_STRIP_ADJACENCY), |
DEBUG_NAMED_VALUE(PIPE_PRIM_TRIANGLES_ADJACENCY), |
DEBUG_NAMED_VALUE(PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY), |
#endif |
DEBUG_NAMED_VALUE_END |
}; |
const char *u_prim_name( unsigned prim ) |
{ |
return debug_dump_enum(pipe_prim_names, 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 |
/** |
* Dump an image to .ppm file. |
* \param format PIPE_FORMAT_x |
* \param cpp bytes per pixel |
* \param width width in pixels |
* \param height height in pixels |
* \param stride row stride in bytes |
*/ |
void debug_dump_image(const char *prefix, |
enum pipe_format format, unsigned cpp, |
unsigned width, unsigned height, |
unsigned stride, |
const void *data) |
{ |
/* write a ppm file */ |
char filename[256]; |
unsigned char *rgb8; |
FILE *f; |
util_snprintf(filename, sizeof(filename), "%s.ppm", prefix); |
rgb8 = MALLOC(height * width * 3); |
if (!rgb8) { |
return; |
} |
util_format_translate( |
PIPE_FORMAT_R8G8B8_UNORM, |
rgb8, width * 3, |
0, 0, |
format, |
data, stride, |
0, 0, width, height); |
/* Must be opened in binary mode or DOS line ending causes data |
* to be read with one byte offset. |
*/ |
f = fopen(filename, "wb"); |
if (f) { |
fprintf(f, "P6\n"); |
fprintf(f, "# ppm-file created by gallium\n"); |
fprintf(f, "%i %i\n", width, height); |
fprintf(f, "255\n"); |
fwrite(rgb8, 1, height * width * 3, f); |
fclose(f); |
} |
else { |
fprintf(stderr, "Can't open %s for writing\n", filename); |
} |
FREE(rgb8); |
} |
/* FIXME: dump resources, not surfaces... */ |
void debug_dump_surface(struct pipe_context *pipe, |
const char *prefix, |
struct pipe_surface *surface) |
{ |
struct pipe_resource *texture; |
struct pipe_transfer *transfer; |
void *data; |
if (!surface) |
return; |
/* XXX: this doesn't necessarily work, as the driver may be using |
* temporary storage for the surface which hasn't been propagated |
* back into the texture. Need to nail down the semantics of views |
* and transfers a bit better before we can say if extra work needs |
* to be done here: |
*/ |
texture = surface->texture; |
data = pipe_transfer_map(pipe, texture, surface->u.tex.level, |
surface->u.tex.first_layer, |
PIPE_TRANSFER_READ, |
0, 0, surface->width, surface->height, &transfer); |
if(!data) |
return; |
debug_dump_image(prefix, |
texture->format, |
util_format_get_blocksize(texture->format), |
util_format_get_nblocksx(texture->format, surface->width), |
util_format_get_nblocksy(texture->format, surface->height), |
transfer->stride, |
data); |
pipe->transfer_unmap(pipe, transfer); |
} |
void debug_dump_texture(struct pipe_context *pipe, |
const char *prefix, |
struct pipe_resource *texture) |
{ |
struct pipe_surface *surface, surf_tmpl; |
if (!texture) |
return; |
/* XXX for now, just dump image for layer=0, level=0 */ |
u_surface_default_template(&surf_tmpl, texture); |
surface = pipe->create_surface(pipe, texture, &surf_tmpl); |
if (surface) { |
debug_dump_surface(pipe, prefix, surface); |
pipe->surface_destroy(pipe, surface); |
} |
} |
#pragma pack(push,2) |
struct bmp_file_header { |
uint16_t bfType; |
uint32_t bfSize; |
uint16_t bfReserved1; |
uint16_t bfReserved2; |
uint32_t bfOffBits; |
}; |
#pragma pack(pop) |
struct bmp_info_header { |
uint32_t biSize; |
int32_t biWidth; |
int32_t biHeight; |
uint16_t biPlanes; |
uint16_t biBitCount; |
uint32_t biCompression; |
uint32_t biSizeImage; |
int32_t biXPelsPerMeter; |
int32_t biYPelsPerMeter; |
uint32_t biClrUsed; |
uint32_t biClrImportant; |
}; |
struct bmp_rgb_quad { |
uint8_t rgbBlue; |
uint8_t rgbGreen; |
uint8_t rgbRed; |
uint8_t rgbAlpha; |
}; |
void |
debug_dump_surface_bmp(struct pipe_context *pipe, |
const char *filename, |
struct pipe_surface *surface) |
{ |
struct pipe_transfer *transfer; |
struct pipe_resource *texture = surface->texture; |
void *ptr; |
ptr = pipe_transfer_map(pipe, texture, surface->u.tex.level, |
surface->u.tex.first_layer, PIPE_TRANSFER_READ, |
0, 0, surface->width, surface->height, &transfer); |
debug_dump_transfer_bmp(pipe, filename, transfer, ptr); |
pipe->transfer_unmap(pipe, transfer); |
} |
void |
debug_dump_transfer_bmp(struct pipe_context *pipe, |
const char *filename, |
struct pipe_transfer *transfer, void *ptr) |
{ |
float *rgba; |
if (!transfer) |
goto error1; |
rgba = MALLOC(transfer->box.width * |
transfer->box.height * |
transfer->box.depth * |
4*sizeof(float)); |
if(!rgba) |
goto error1; |
pipe_get_tile_rgba(transfer, ptr, 0, 0, |
transfer->box.width, transfer->box.height, |
rgba); |
debug_dump_float_rgba_bmp(filename, |
transfer->box.width, transfer->box.height, |
rgba, transfer->box.width); |
FREE(rgba); |
error1: |
; |
} |
void |
debug_dump_float_rgba_bmp(const char *filename, |
unsigned width, unsigned height, |
float *rgba, unsigned stride) |
{ |
FILE *stream; |
struct bmp_file_header bmfh; |
struct bmp_info_header bmih; |
unsigned x, y; |
if(!rgba) |
goto error1; |
bmfh.bfType = 0x4d42; |
bmfh.bfSize = 14 + 40 + height*width*4; |
bmfh.bfReserved1 = 0; |
bmfh.bfReserved2 = 0; |
bmfh.bfOffBits = 14 + 40; |
bmih.biSize = 40; |
bmih.biWidth = width; |
bmih.biHeight = height; |
bmih.biPlanes = 1; |
bmih.biBitCount = 32; |
bmih.biCompression = 0; |
bmih.biSizeImage = height*width*4; |
bmih.biXPelsPerMeter = 0; |
bmih.biYPelsPerMeter = 0; |
bmih.biClrUsed = 0; |
bmih.biClrImportant = 0; |
stream = fopen(filename, "wb"); |
if(!stream) |
goto error1; |
fwrite(&bmfh, 14, 1, stream); |
fwrite(&bmih, 40, 1, stream); |
y = height; |
while(y--) { |
float *ptr = rgba + (stride * y * 4); |
for(x = 0; x < width; ++x) |
{ |
struct bmp_rgb_quad pixel; |
pixel.rgbRed = float_to_ubyte(ptr[x*4 + 0]); |
pixel.rgbGreen = float_to_ubyte(ptr[x*4 + 1]); |
pixel.rgbBlue = float_to_ubyte(ptr[x*4 + 2]); |
pixel.rgbAlpha = float_to_ubyte(ptr[x*4 + 3]); |
fwrite(&pixel, 1, 4, stream); |
} |
} |
fclose(stream); |
error1: |
; |
} |
/** |
* Print PIPE_TRANSFER_x flags with a message. |
*/ |
void |
debug_print_transfer_flags(const char *msg, unsigned usage) |
{ |
#define FLAG(x) { x, #x } |
static const struct { |
unsigned bit; |
const char *name; |
} flags[] = { |
FLAG(PIPE_TRANSFER_READ), |
FLAG(PIPE_TRANSFER_WRITE), |
FLAG(PIPE_TRANSFER_MAP_DIRECTLY), |
FLAG(PIPE_TRANSFER_DISCARD_RANGE), |
FLAG(PIPE_TRANSFER_DONTBLOCK), |
FLAG(PIPE_TRANSFER_UNSYNCHRONIZED), |
FLAG(PIPE_TRANSFER_FLUSH_EXPLICIT), |
FLAG(PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) |
}; |
unsigned i; |
debug_printf("%s ", msg); |
for (i = 0; i < Elements(flags); i++) { |
if (usage & flags[i].bit) { |
debug_printf("%s", flags[i].name); |
usage &= ~flags[i].bit; |
if (usage) { |
debug_printf(" | "); |
} |
} |
} |
debug_printf("\n"); |
#undef FLAG |
} |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_debug.h |
---|
0,0 → 1,459 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* 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 TUNGSTEN GRAPHICS 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. |
* |
**************************************************************************/ |
/** |
* @file |
* Cross-platform debugging helpers. |
* |
* For now it just has assert and printf replacements, but it might be extended |
* with stack trace reports and more advanced logging in the near future. |
* |
* @author Jose Fonseca <jrfonseca@tungstengraphics.com> |
*/ |
#ifndef U_DEBUG_H_ |
#define U_DEBUG_H_ |
#include "os/os_misc.h" |
#include "pipe/p_format.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
#if defined(__GNUC__) |
#define _util_printf_format(fmt, list) __attribute__ ((format (printf, fmt, list))) |
#else |
#define _util_printf_format(fmt, list) |
#endif |
void _debug_vprintf(const char *format, va_list ap); |
static INLINE void |
_debug_printf(const char *format, ...) |
{ |
va_list ap; |
va_start(ap, format); |
_debug_vprintf(format, ap); |
va_end(ap); |
} |
/** |
* Print debug messages. |
* |
* The actual channel used to output debug message is platform specific. To |
* avoid misformating or truncation, follow these rules of thumb: |
* - output whole lines |
* - avoid outputing large strings (512 bytes is the current maximum length |
* that is guaranteed to be printed in all platforms) |
*/ |
#if !defined(PIPE_OS_HAIKU) |
static INLINE void |
debug_printf(const char *format, ...) _util_printf_format(1,2); |
static INLINE void |
debug_printf(const char *format, ...) |
{ |
#ifdef DEBUG |
va_list ap; |
va_start(ap, format); |
_debug_vprintf(format, ap); |
va_end(ap); |
#else |
(void) format; /* silence warning */ |
#endif |
} |
#else /* is Haiku */ |
/* Haiku provides debug_printf in libroot with OS.h */ |
#include <OS.h> |
#endif |
/* |
* ... isn't portable so we need to pass arguments in parentheses. |
* |
* usage: |
* debug_printf_once(("answer: %i\n", 42)); |
*/ |
#define debug_printf_once(args) \ |
do { \ |
static boolean once = TRUE; \ |
if (once) { \ |
once = FALSE; \ |
debug_printf args; \ |
} \ |
} while (0) |
#ifdef DEBUG |
#define debug_vprintf(_format, _ap) _debug_vprintf(_format, _ap) |
#else |
#define debug_vprintf(_format, _ap) ((void)0) |
#endif |
#ifdef DEBUG |
/** |
* Dump a blob in hex to the same place that debug_printf sends its |
* messages. |
*/ |
void debug_print_blob( const char *name, const void *blob, unsigned size ); |
/* Print a message along with a prettified format string |
*/ |
void debug_print_format(const char *msg, unsigned fmt ); |
#else |
#define debug_print_blob(_name, _blob, _size) ((void)0) |
#define debug_print_format(_msg, _fmt) ((void)0) |
#endif |
/** |
* Hard-coded breakpoint. |
*/ |
#ifdef DEBUG |
#define debug_break() os_break() |
#else /* !DEBUG */ |
#define debug_break() ((void)0) |
#endif /* !DEBUG */ |
long |
debug_get_num_option(const char *name, long dfault); |
void _debug_assert_fail(const char *expr, |
const char *file, |
unsigned line, |
const char *function); |
/** |
* Assert macro |
* |
* Do not expect that the assert call terminates -- errors must be handled |
* regardless of assert behavior. |
* |
* For non debug builds the assert macro will expand to a no-op, so do not |
* call functions with side effects in the assert expression. |
*/ |
#ifdef DEBUG |
#define debug_assert(expr) ((expr) ? (void)0 : _debug_assert_fail(#expr, __FILE__, __LINE__, __FUNCTION__)) |
#else |
#define debug_assert(expr) do { } while (0 && (expr)) |
#endif |
/** Override standard assert macro */ |
#ifdef assert |
#undef assert |
#endif |
#define assert(expr) debug_assert(expr) |
/** |
* Output the current function name. |
*/ |
#ifdef DEBUG |
#define debug_checkpoint() \ |
_debug_printf("%s\n", __FUNCTION__) |
#else |
#define debug_checkpoint() \ |
((void)0) |
#endif |
/** |
* Output the full source code position. |
*/ |
#ifdef DEBUG |
#define debug_checkpoint_full() \ |
_debug_printf("%s:%u:%s\n", __FILE__, __LINE__, __FUNCTION__) |
#else |
#define debug_checkpoint_full() \ |
((void)0) |
#endif |
/** |
* Output a warning message. Muted on release version. |
*/ |
#ifdef DEBUG |
#define debug_warning(__msg) \ |
_debug_printf("%s:%u:%s: warning: %s\n", __FILE__, __LINE__, __FUNCTION__, __msg) |
#else |
#define debug_warning(__msg) \ |
((void)0) |
#endif |
/** |
* Emit a warning message, but only once. |
*/ |
#ifdef DEBUG |
#define debug_warn_once(__msg) \ |
do { \ |
static bool warned = FALSE; \ |
if (!warned) { \ |
_debug_printf("%s:%u:%s: one time warning: %s\n", \ |
__FILE__, __LINE__, __FUNCTION__, __msg); \ |
warned = TRUE; \ |
} \ |
} while (0) |
#else |
#define debug_warn_once(__msg) \ |
((void)0) |
#endif |
/** |
* Output an error message. Not muted on release version. |
*/ |
#ifdef DEBUG |
#define debug_error(__msg) \ |
_debug_printf("%s:%u:%s: error: %s\n", __FILE__, __LINE__, __FUNCTION__, __msg) |
#else |
#define debug_error(__msg) \ |
_debug_printf("error: %s\n", __msg) |
#endif |
/** |
* Used by debug_dump_enum and debug_dump_flags to describe symbols. |
*/ |
struct debug_named_value |
{ |
const char *name; |
unsigned long value; |
const char *desc; |
}; |
/** |
* Some C pre-processor magic to simplify creating named values. |
* |
* Example: |
* @code |
* static const debug_named_value my_names[] = { |
* DEBUG_NAMED_VALUE(MY_ENUM_VALUE_X), |
* DEBUG_NAMED_VALUE(MY_ENUM_VALUE_Y), |
* DEBUG_NAMED_VALUE(MY_ENUM_VALUE_Z), |
* DEBUG_NAMED_VALUE_END |
* }; |
* |
* ... |
* debug_printf("%s = %s\n", |
* name, |
* debug_dump_enum(my_names, my_value)); |
* ... |
* @endcode |
*/ |
#define DEBUG_NAMED_VALUE(__symbol) {#__symbol, (unsigned long)__symbol, NULL} |
#define DEBUG_NAMED_VALUE_WITH_DESCRIPTION(__symbol, __desc) {#__symbol, (unsigned long)__symbol, __desc} |
#define DEBUG_NAMED_VALUE_END {NULL, 0, NULL} |
/** |
* Convert a enum value to a string. |
*/ |
const char * |
debug_dump_enum(const struct debug_named_value *names, |
unsigned long value); |
const char * |
debug_dump_enum_noprefix(const struct debug_named_value *names, |
const char *prefix, |
unsigned long value); |
/** |
* Convert binary flags value to a string. |
*/ |
const char * |
debug_dump_flags(const struct debug_named_value *names, |
unsigned long value); |
/** |
* 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. |
* |
* On Windows it reads C:\gallium.cfg, which is a text file with CR+LF line |
* endings with one option per line as |
* |
* NAME=value |
* |
* This file must be terminated with an extra empty line. |
*/ |
const char * |
debug_get_option(const char *name, const char *dfault); |
boolean |
debug_get_bool_option(const char *name, boolean dfault); |
long |
debug_get_num_option(const char *name, long dfault); |
unsigned long |
debug_get_flags_option(const char *name, |
const struct debug_named_value *flags, |
unsigned long dfault); |
#define DEBUG_GET_ONCE_BOOL_OPTION(sufix, name, dfault) \ |
static boolean \ |
debug_get_option_ ## sufix (void) \ |
{ \ |
static boolean first = TRUE; \ |
static boolean value; \ |
if (first) { \ |
first = FALSE; \ |
value = debug_get_bool_option(name, dfault); \ |
} \ |
return value; \ |
} |
#define DEBUG_GET_ONCE_NUM_OPTION(sufix, name, dfault) \ |
static long \ |
debug_get_option_ ## sufix (void) \ |
{ \ |
static boolean first = TRUE; \ |
static long value; \ |
if (first) { \ |
first = FALSE; \ |
value = debug_get_num_option(name, dfault); \ |
} \ |
return value; \ |
} |
#define DEBUG_GET_ONCE_FLAGS_OPTION(sufix, name, flags, dfault) \ |
static unsigned long \ |
debug_get_option_ ## sufix (void) \ |
{ \ |
static boolean first = TRUE; \ |
static unsigned long value; \ |
if (first) { \ |
first = FALSE; \ |
value = debug_get_flags_option(name, flags, dfault); \ |
} \ |
return value; \ |
} |
unsigned long |
debug_memory_begin(void); |
void |
debug_memory_end(unsigned long beginning); |
#ifdef DEBUG |
struct pipe_context; |
struct pipe_surface; |
struct pipe_transfer; |
struct pipe_resource; |
void debug_dump_image(const char *prefix, |
enum pipe_format format, unsigned cpp, |
unsigned width, unsigned height, |
unsigned stride, |
const void *data); |
void debug_dump_surface(struct pipe_context *pipe, |
const char *prefix, |
struct pipe_surface *surface); |
void debug_dump_texture(struct pipe_context *pipe, |
const char *prefix, |
struct pipe_resource *texture); |
void debug_dump_surface_bmp(struct pipe_context *pipe, |
const char *filename, |
struct pipe_surface *surface); |
void debug_dump_transfer_bmp(struct pipe_context *pipe, |
const char *filename, |
struct pipe_transfer *transfer, void *ptr); |
void debug_dump_float_rgba_bmp(const char *filename, |
unsigned width, unsigned height, |
float *rgba, unsigned stride); |
#else |
#define debug_dump_image(prefix, format, cpp, width, height, stride, data) ((void)0) |
#define debug_dump_surface(pipe, prefix, surface) ((void)0) |
#define debug_dump_surface_bmp(pipe, filename, surface) ((void)0) |
#define debug_dump_transfer_bmp(filename, transfer, ptr) ((void)0) |
#define debug_dump_float_rgba_bmp(filename, width, height, rgba, stride) ((void)0) |
#endif |
void |
debug_print_transfer_flags(const char *msg, unsigned usage); |
#ifdef __cplusplus |
} |
#endif |
#endif /* U_DEBUG_H_ */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_debug_describe.c |
---|
0,0 → 1,91 |
/************************************************************************** |
* |
* Copyright 2010 Luca Barbieri |
* |
* 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, sublicense, 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 NONINFRINGEMENT. |
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "pipe/p_state.h" |
#include "util/u_format.h" |
#include "util/u_debug_describe.h" |
#include "util/u_string.h" |
void |
debug_describe_reference(char* buf, const struct pipe_reference*ptr) |
{ |
strcpy(buf, "pipe_object"); |
} |
void |
debug_describe_resource(char* buf, const struct pipe_resource *ptr) |
{ |
switch(ptr->target) |
{ |
case PIPE_BUFFER: |
util_sprintf(buf, "pipe_buffer<%u>", (unsigned)util_format_get_stride(ptr->format, ptr->width0)); |
break; |
case PIPE_TEXTURE_1D: |
util_sprintf(buf, "pipe_texture1d<%u,%s,%u>", ptr->width0, util_format_short_name(ptr->format), ptr->last_level); |
break; |
case PIPE_TEXTURE_2D: |
util_sprintf(buf, "pipe_texture2d<%u,%u,%s,%u>", ptr->width0, ptr->height0, util_format_short_name(ptr->format), ptr->last_level); |
break; |
case PIPE_TEXTURE_RECT: |
util_sprintf(buf, "pipe_texture_rect<%u,%u,%s>", ptr->width0, ptr->height0, util_format_short_name(ptr->format)); |
break; |
case PIPE_TEXTURE_CUBE: |
util_sprintf(buf, "pipe_texture_cube<%u,%u,%s,%u>", ptr->width0, ptr->height0, util_format_short_name(ptr->format), ptr->last_level); |
break; |
case PIPE_TEXTURE_3D: |
util_sprintf(buf, "pipe_texture3d<%u,%u,%u,%s,%u>", ptr->width0, ptr->height0, ptr->depth0, util_format_short_name(ptr->format), ptr->last_level); |
break; |
default: |
util_sprintf(buf, "pipe_martian_resource<%u>", ptr->target); |
break; |
} |
} |
void |
debug_describe_surface(char* buf, const struct pipe_surface *ptr) |
{ |
char res[128]; |
debug_describe_resource(res, ptr->texture); |
util_sprintf(buf, "pipe_surface<%s,%u,%u,%u>", res, ptr->u.tex.level, ptr->u.tex.first_layer, ptr->u.tex.last_layer); |
} |
void |
debug_describe_sampler_view(char* buf, const struct pipe_sampler_view *ptr) |
{ |
char res[128]; |
debug_describe_resource(res, ptr->texture); |
util_sprintf(buf, "pipe_sampler_view<%s,%s>", res, util_format_short_name(ptr->format)); |
} |
void |
debug_describe_so_target(char* buf, |
const struct pipe_stream_output_target *ptr) |
{ |
char res[128]; |
debug_describe_resource(res, ptr->buffer); |
util_sprintf(buf, "pipe_stream_output_target<%s,%u,%u>", res, |
ptr->buffer_offset, ptr->buffer_size); |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_debug_describe.h |
---|
0,0 → 1,51 |
/************************************************************************** |
* |
* Copyright 2010 Luca Barbieri |
* |
* 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, sublicense, 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 NONINFRINGEMENT. |
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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_DEBUG_DESCRIBE_H_ |
#define U_DEBUG_DESCRIBE_H_ |
#ifdef __cplusplus |
extern "C" { |
#endif |
struct pipe_reference; |
struct pipe_resource; |
struct pipe_surface; |
struct pipe_sampler_view; |
/* a 256-byte buffer is necessary and sufficient */ |
void debug_describe_reference(char* buf, const struct pipe_reference*ptr); |
void debug_describe_resource(char* buf, const struct pipe_resource *ptr); |
void debug_describe_surface(char* buf, const struct pipe_surface *ptr); |
void debug_describe_sampler_view(char* buf, const struct pipe_sampler_view *ptr); |
void debug_describe_so_target(char* buf, |
const struct pipe_stream_output_target *ptr); |
#ifdef __cplusplus |
} |
#endif |
#endif /* U_DEBUG_DESCRIBE_H_ */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_debug_memory.c |
---|
0,0 → 1,451 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* 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 TUNGSTEN GRAPHICS 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. |
* |
**************************************************************************/ |
/** |
* @file |
* Memory debugging. |
* |
* @author José Fonseca <jrfonseca@tungstengraphics.com> |
*/ |
#include "pipe/p_config.h" |
#define DEBUG_MEMORY_IMPLEMENTATION |
#include "os/os_memory.h" |
#include "os/os_memory_debug.h" |
#include "os/os_thread.h" |
#include "util/u_debug.h" |
#include "util/u_debug_stack.h" |
#include "util/u_double_list.h" |
#define DEBUG_MEMORY_MAGIC 0x6e34090aU |
#define DEBUG_MEMORY_STACK 0 /* XXX: disabled until we have symbol lookup */ |
/** |
* Set to 1 to enable checking of freed blocks of memory. |
* Basically, don't really deallocate freed memory; keep it in the list |
* but mark it as freed and do extra checking in debug_memory_check(). |
* This can detect some cases of use-after-free. But note that since we |
* never really free anything this will use a lot of memory. |
*/ |
#define DEBUG_FREED_MEMORY 0 |
#define DEBUG_FREED_BYTE 0x33 |
struct debug_memory_header |
{ |
struct list_head head; |
unsigned long no; |
const char *file; |
unsigned line; |
const char *function; |
#if DEBUG_MEMORY_STACK |
struct debug_stack_frame backtrace[DEBUG_MEMORY_STACK]; |
#endif |
size_t size; |
#if DEBUG_FREED_MEMORY |
boolean freed; /**< Is this a freed block? */ |
#endif |
unsigned magic; |
unsigned tag; |
}; |
struct debug_memory_footer |
{ |
unsigned magic; |
}; |
static struct list_head list = { &list, &list }; |
pipe_static_mutex(list_mutex); |
static unsigned long last_no = 0; |
static INLINE struct debug_memory_header * |
header_from_data(void *data) |
{ |
if(data) |
return (struct debug_memory_header *)((char *)data - sizeof(struct debug_memory_header)); |
else |
return NULL; |
} |
static INLINE void * |
data_from_header(struct debug_memory_header *hdr) |
{ |
if(hdr) |
return (void *)((char *)hdr + sizeof(struct debug_memory_header)); |
else |
return NULL; |
} |
static INLINE struct debug_memory_footer * |
footer_from_header(struct debug_memory_header *hdr) |
{ |
if(hdr) |
return (struct debug_memory_footer *)((char *)hdr + sizeof(struct debug_memory_header) + hdr->size); |
else |
return NULL; |
} |
void * |
debug_malloc(const char *file, unsigned line, const char *function, |
size_t size) |
{ |
struct debug_memory_header *hdr; |
struct debug_memory_footer *ftr; |
hdr = os_malloc(sizeof(*hdr) + size + sizeof(*ftr)); |
if(!hdr) { |
debug_printf("%s:%u:%s: out of memory when trying to allocate %lu bytes\n", |
file, line, function, |
(long unsigned)size); |
return NULL; |
} |
hdr->no = last_no++; |
hdr->file = file; |
hdr->line = line; |
hdr->function = function; |
hdr->size = size; |
hdr->magic = DEBUG_MEMORY_MAGIC; |
hdr->tag = 0; |
#if DEBUG_FREED_MEMORY |
hdr->freed = FALSE; |
#endif |
#if DEBUG_MEMORY_STACK |
debug_backtrace_capture(hdr->backtrace, 0, DEBUG_MEMORY_STACK); |
#endif |
ftr = footer_from_header(hdr); |
ftr->magic = DEBUG_MEMORY_MAGIC; |
pipe_mutex_lock(list_mutex); |
LIST_ADDTAIL(&hdr->head, &list); |
pipe_mutex_unlock(list_mutex); |
return data_from_header(hdr); |
} |
void |
debug_free(const char *file, unsigned line, const char *function, |
void *ptr) |
{ |
struct debug_memory_header *hdr; |
struct debug_memory_footer *ftr; |
if(!ptr) |
return; |
hdr = header_from_data(ptr); |
if(hdr->magic != DEBUG_MEMORY_MAGIC) { |
debug_printf("%s:%u:%s: freeing bad or corrupted memory %p\n", |
file, line, function, |
ptr); |
debug_assert(0); |
return; |
} |
ftr = footer_from_header(hdr); |
if(ftr->magic != DEBUG_MEMORY_MAGIC) { |
debug_printf("%s:%u:%s: buffer overflow %p\n", |
hdr->file, hdr->line, hdr->function, |
ptr); |
debug_assert(0); |
} |
#if DEBUG_FREED_MEMORY |
/* Check for double-free */ |
assert(!hdr->freed); |
/* Mark the block as freed but don't really free it */ |
hdr->freed = TRUE; |
/* Save file/line where freed */ |
hdr->file = file; |
hdr->line = line; |
/* set freed memory to special value */ |
memset(ptr, DEBUG_FREED_BYTE, hdr->size); |
#else |
pipe_mutex_lock(list_mutex); |
LIST_DEL(&hdr->head); |
pipe_mutex_unlock(list_mutex); |
hdr->magic = 0; |
ftr->magic = 0; |
os_free(hdr); |
#endif |
} |
void * |
debug_calloc(const char *file, unsigned line, const char *function, |
size_t count, size_t size ) |
{ |
void *ptr = debug_malloc( file, line, function, count * size ); |
if( ptr ) |
memset( ptr, 0, count * size ); |
return ptr; |
} |
void * |
debug_realloc(const char *file, unsigned line, const char *function, |
void *old_ptr, size_t old_size, size_t new_size ) |
{ |
struct debug_memory_header *old_hdr, *new_hdr; |
struct debug_memory_footer *old_ftr, *new_ftr; |
void *new_ptr; |
if(!old_ptr) |
return debug_malloc( file, line, function, new_size ); |
if(!new_size) { |
debug_free( file, line, function, old_ptr ); |
return NULL; |
} |
old_hdr = header_from_data(old_ptr); |
if(old_hdr->magic != DEBUG_MEMORY_MAGIC) { |
debug_printf("%s:%u:%s: reallocating bad or corrupted memory %p\n", |
file, line, function, |
old_ptr); |
debug_assert(0); |
return NULL; |
} |
old_ftr = footer_from_header(old_hdr); |
if(old_ftr->magic != DEBUG_MEMORY_MAGIC) { |
debug_printf("%s:%u:%s: buffer overflow %p\n", |
old_hdr->file, old_hdr->line, old_hdr->function, |
old_ptr); |
debug_assert(0); |
} |
/* alloc new */ |
new_hdr = os_malloc(sizeof(*new_hdr) + new_size + sizeof(*new_ftr)); |
if(!new_hdr) { |
debug_printf("%s:%u:%s: out of memory when trying to allocate %lu bytes\n", |
file, line, function, |
(long unsigned)new_size); |
return NULL; |
} |
new_hdr->no = old_hdr->no; |
new_hdr->file = old_hdr->file; |
new_hdr->line = old_hdr->line; |
new_hdr->function = old_hdr->function; |
new_hdr->size = new_size; |
new_hdr->magic = DEBUG_MEMORY_MAGIC; |
new_hdr->tag = 0; |
#if DEBUG_FREED_MEMORY |
new_hdr->freed = FALSE; |
#endif |
new_ftr = footer_from_header(new_hdr); |
new_ftr->magic = DEBUG_MEMORY_MAGIC; |
pipe_mutex_lock(list_mutex); |
LIST_REPLACE(&old_hdr->head, &new_hdr->head); |
pipe_mutex_unlock(list_mutex); |
/* copy data */ |
new_ptr = data_from_header(new_hdr); |
memcpy( new_ptr, old_ptr, old_size < new_size ? old_size : new_size ); |
/* free old */ |
old_hdr->magic = 0; |
old_ftr->magic = 0; |
os_free(old_hdr); |
return new_ptr; |
} |
unsigned long |
debug_memory_begin(void) |
{ |
return last_no; |
} |
void |
debug_memory_end(unsigned long start_no) |
{ |
size_t total_size = 0; |
struct list_head *entry; |
if(start_no == last_no) |
return; |
entry = list.prev; |
for (; entry != &list; entry = entry->prev) { |
struct debug_memory_header *hdr; |
void *ptr; |
struct debug_memory_footer *ftr; |
hdr = LIST_ENTRY(struct debug_memory_header, entry, head); |
ptr = data_from_header(hdr); |
ftr = footer_from_header(hdr); |
if(hdr->magic != DEBUG_MEMORY_MAGIC) { |
debug_printf("%s:%u:%s: bad or corrupted memory %p\n", |
hdr->file, hdr->line, hdr->function, |
ptr); |
debug_assert(0); |
} |
if((start_no <= hdr->no && hdr->no < last_no) || |
(last_no < start_no && (hdr->no < last_no || start_no <= hdr->no))) { |
debug_printf("%s:%u:%s: %lu bytes at %p not freed\n", |
hdr->file, hdr->line, hdr->function, |
(unsigned long) hdr->size, ptr); |
#if DEBUG_MEMORY_STACK |
debug_backtrace_dump(hdr->backtrace, DEBUG_MEMORY_STACK); |
#endif |
total_size += hdr->size; |
} |
if(ftr->magic != DEBUG_MEMORY_MAGIC) { |
debug_printf("%s:%u:%s: buffer overflow %p\n", |
hdr->file, hdr->line, hdr->function, |
ptr); |
debug_assert(0); |
} |
} |
if(total_size) { |
debug_printf("Total of %lu KB of system memory apparently leaked\n", |
(unsigned long) (total_size + 1023)/1024); |
} |
else { |
debug_printf("No memory leaks detected.\n"); |
} |
} |
/** |
* Put a tag (arbitrary integer) on a memory block. |
* Can be useful for debugging. |
*/ |
void |
debug_memory_tag(void *ptr, unsigned tag) |
{ |
struct debug_memory_header *hdr; |
if (!ptr) |
return; |
hdr = header_from_data(ptr); |
if (hdr->magic != DEBUG_MEMORY_MAGIC) { |
debug_printf("%s corrupted memory at %p\n", __FUNCTION__, ptr); |
debug_assert(0); |
} |
hdr->tag = tag; |
} |
/** |
* Check the given block of memory for validity/corruption. |
*/ |
void |
debug_memory_check_block(void *ptr) |
{ |
struct debug_memory_header *hdr; |
struct debug_memory_footer *ftr; |
if (!ptr) |
return; |
hdr = header_from_data(ptr); |
ftr = footer_from_header(hdr); |
if (hdr->magic != DEBUG_MEMORY_MAGIC) { |
debug_printf("%s:%u:%s: bad or corrupted memory %p\n", |
hdr->file, hdr->line, hdr->function, ptr); |
debug_assert(0); |
} |
if (ftr->magic != DEBUG_MEMORY_MAGIC) { |
debug_printf("%s:%u:%s: buffer overflow %p\n", |
hdr->file, hdr->line, hdr->function, ptr); |
debug_assert(0); |
} |
} |
/** |
* We can periodically call this from elsewhere to do a basic sanity |
* check of the heap memory we've allocated. |
*/ |
void |
debug_memory_check(void) |
{ |
struct list_head *entry; |
entry = list.prev; |
for (; entry != &list; entry = entry->prev) { |
struct debug_memory_header *hdr; |
struct debug_memory_footer *ftr; |
const char *ptr; |
hdr = LIST_ENTRY(struct debug_memory_header, entry, head); |
ftr = footer_from_header(hdr); |
ptr = (const char *) data_from_header(hdr); |
if (hdr->magic != DEBUG_MEMORY_MAGIC) { |
debug_printf("%s:%u:%s: bad or corrupted memory %p\n", |
hdr->file, hdr->line, hdr->function, ptr); |
debug_assert(0); |
} |
if (ftr->magic != DEBUG_MEMORY_MAGIC) { |
debug_printf("%s:%u:%s: buffer overflow %p\n", |
hdr->file, hdr->line, hdr->function, ptr); |
debug_assert(0); |
} |
#if DEBUG_FREED_MEMORY |
/* If this block is marked as freed, check that it hasn't been touched */ |
if (hdr->freed) { |
int i; |
for (i = 0; i < hdr->size; i++) { |
if (ptr[i] != DEBUG_FREED_BYTE) { |
debug_printf("Memory error: byte %d of block at %p of size %d is 0x%x\n", |
i, ptr, hdr->size, ptr[i]); |
debug_printf("Block was freed at %s:%d\n", hdr->file, hdr->line); |
} |
assert(ptr[i] == DEBUG_FREED_BYTE); |
} |
} |
#endif |
} |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_debug_refcnt.c |
---|
0,0 → 1,195 |
/************************************************************************** |
* |
* Copyright 2010 Luca Barbieri |
* |
* 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, sublicense, 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 NONINFRINGEMENT. |
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. |
* |
**************************************************************************/ |
#if defined(DEBUG) |
/* see http://www.mozilla.org/performance/refcnt-balancer.html for what do with the output |
* on Linux, use tools/addr2line.sh to postprocess it before anything else |
**/ |
#include <stdio.h> |
#include "util/u_debug.h" |
#include "util/u_debug_refcnt.h" |
#include "util/u_debug_stack.h" |
#include "util/u_debug_symbol.h" |
#include "util/u_string.h" |
#include "util/u_hash_table.h" |
#include "os/os_thread.h" |
int debug_refcnt_state; |
FILE* stream; |
/* TODO: maybe move this serial machinery to a stand-alone module and expose it? */ |
pipe_static_mutex(serials_mutex); |
static struct util_hash_table* serials_hash; |
static unsigned serials_last; |
static unsigned hash_ptr(void* p) |
{ |
return (unsigned)(uintptr_t)p; |
} |
static int compare_ptr(void* a, void* b) |
{ |
if(a == b) |
return 0; |
else if(a < b) |
return -1; |
else |
return 1; |
} |
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); |
serial = (unsigned)(uintptr_t)util_hash_table_get(serials_hash, p); |
if(!serial) |
{ |
/* time to stop logging... (you'll have a 100 GB logfile at least at this point) |
* TODO: avoid this |
*/ |
serial = ++serials_last; |
if(!serial) |
{ |
debug_error("More than 2^32 objects detected, aborting.\n"); |
os_abort(); |
} |
util_hash_table_set(serials_hash, p, (void*)(uintptr_t)serial); |
found = FALSE; |
} |
pipe_mutex_unlock(serials_mutex); |
*pserial = serial; |
return found; |
} |
static void debug_serial_delete(void* p) |
{ |
pipe_mutex_lock(serials_mutex); |
util_hash_table_remove(serials_hash, p); |
pipe_mutex_unlock(serials_mutex); |
} |
#define STACK_LEN 64 |
static void dump_stack(const char* symbols[STACK_LEN]) |
{ |
unsigned i; |
for(i = 0; i < STACK_LEN; ++i) |
{ |
if(symbols[i]) |
fprintf(stream, "%s\n", symbols[i]); |
} |
fprintf(stream, "\n"); |
} |
void debug_reference_slowpath(const struct pipe_reference* p, debug_reference_descriptor get_desc, int change) |
{ |
if(debug_refcnt_state < 0) |
return; |
if(!debug_refcnt_state) |
{ |
const char* filename = debug_get_option("GALLIUM_REFCNT_LOG", NULL); |
if(filename && filename[0]) |
stream = fopen(filename, "wt"); |
if(stream) |
debug_refcnt_state = 1; |
else |
debug_refcnt_state = -1; |
} |
if(debug_refcnt_state > 0) |
{ |
struct debug_stack_frame frames[STACK_LEN]; |
const char* symbols[STACK_LEN]; |
char buf[1024]; |
unsigned i; |
unsigned refcnt = p->count; |
unsigned serial; |
boolean existing = debug_serial((void*)p, &serial); |
debug_backtrace_capture(frames, 1, STACK_LEN); |
for(i = 0; i < STACK_LEN; ++i) |
{ |
if(frames[i].function) |
symbols[i] = debug_symbol_name_cached(frames[i].function); |
else |
symbols[i] = 0; |
} |
get_desc(buf, p); |
if(!existing) |
{ |
fprintf(stream, "<%s> %p %u Create\n", buf, (void *) p, serial); |
dump_stack(symbols); |
/* this is there to provide a gradual change even if we don't see the initialization */ |
for(i = 1; i <= refcnt - change; ++i) |
{ |
fprintf(stream, "<%s> %p %u AddRef %u\n", buf, (void *) p, |
serial, i); |
dump_stack(symbols); |
} |
} |
if(change) |
{ |
fprintf(stream, "<%s> %p %u %s %u\n", buf, (void *) p, serial, |
change > 0 ? "AddRef" : "Release", refcnt); |
dump_stack(symbols); |
} |
if(!refcnt) |
{ |
debug_serial_delete((void*)p); |
fprintf(stream, "<%s> %p %u Destroy\n", buf, (void *) p, serial); |
dump_stack(symbols); |
} |
fflush(stream); |
} |
} |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_debug_refcnt.h |
---|
0,0 → 1,63 |
/************************************************************************** |
* |
* Copyright 2010 Luca Barbieri |
* |
* 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, sublicense, 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 NONINFRINGEMENT. |
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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_DEBUG_REFCNT_H_ |
#define U_DEBUG_REFCNT_H_ |
#include "pipe/p_config.h" |
#include "pipe/p_state.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
typedef void (*debug_reference_descriptor)(char*, const struct pipe_reference*); |
#if defined(DEBUG) && (!defined(PIPE_OS_WINDOWS) || defined(PIPE_SUBSYSTEM_WINDOWS_USER)) |
extern int debug_refcnt_state; |
void debug_reference_slowpath(const struct pipe_reference* p, debug_reference_descriptor get_desc, int change); |
static INLINE void debug_reference(const struct pipe_reference* p, debug_reference_descriptor get_desc, int change) |
{ |
if (debug_refcnt_state >= 0) |
debug_reference_slowpath(p, get_desc, change); |
} |
#else |
static INLINE void debug_reference(const struct pipe_reference* p, debug_reference_descriptor get_desc, int change) |
{ |
} |
#endif |
#ifdef __cplusplus |
} |
#endif |
#endif /* U_DEBUG_REFCNT_H_ */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_debug_stack.c |
---|
0,0 → 1,161 |
/************************************************************************** |
* |
* Copyright 2009 VMware, Inc. |
* 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 VMWARE 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. |
* |
**************************************************************************/ |
/** |
* @file |
* Stack backtracing. |
* |
* @author Jose Fonseca <jfonseca@vmware.com> |
*/ |
#include "u_debug.h" |
#include "u_debug_symbol.h" |
#include "u_debug_stack.h" |
#if defined(PIPE_OS_WINDOWS) |
#include <windows.h> |
#endif |
/** |
* Capture stack backtrace. |
* |
* NOTE: The implementation of this function is quite big, but it is important not to |
* break it down in smaller functions to avoid adding new frames to the calling stack. |
*/ |
void |
debug_backtrace_capture(struct debug_stack_frame *backtrace, |
unsigned start_frame, |
unsigned nr_frames) |
{ |
const void **frame_pointer = NULL; |
unsigned i = 0; |
if (!nr_frames) { |
return; |
} |
/* |
* On Windows try obtaining the stack backtrace via CaptureStackBackTrace. |
* |
* It works reliably both for x86 for x86_64. |
*/ |
#if defined(PIPE_OS_WINDOWS) |
{ |
typedef USHORT (WINAPI *PFNCAPTURESTACKBACKTRACE)(ULONG, ULONG, PVOID *, PULONG); |
static PFNCAPTURESTACKBACKTRACE pfnCaptureStackBackTrace = NULL; |
if (!pfnCaptureStackBackTrace) { |
static HMODULE hModule = NULL; |
if (!hModule) { |
hModule = LoadLibraryA("kernel32"); |
assert(hModule); |
} |
if (hModule) { |
pfnCaptureStackBackTrace = (PFNCAPTURESTACKBACKTRACE)GetProcAddress(hModule, |
"RtlCaptureStackBackTrace"); |
} |
} |
if (pfnCaptureStackBackTrace) { |
/* |
* Skip this (debug_backtrace_capture) function's frame. |
*/ |
start_frame += 1; |
assert(start_frame + nr_frames < 63); |
i = pfnCaptureStackBackTrace(start_frame, nr_frames, (PVOID *) &backtrace->function, NULL); |
/* Pad remaing requested frames with NULL */ |
while (i < nr_frames) { |
backtrace[i++].function = NULL; |
} |
return; |
} |
} |
#endif |
#if defined(PIPE_CC_GCC) |
frame_pointer = ((const void **)__builtin_frame_address(1)); |
#elif defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86) |
__asm { |
mov frame_pointer, ebp |
} |
frame_pointer = (const void **)frame_pointer[0]; |
#else |
frame_pointer = NULL; |
#endif |
#ifdef PIPE_ARCH_X86 |
while(nr_frames) { |
const void **next_frame_pointer; |
if(!frame_pointer) |
break; |
if(start_frame) |
--start_frame; |
else { |
backtrace[i++].function = frame_pointer[1]; |
--nr_frames; |
} |
next_frame_pointer = (const void **)frame_pointer[0]; |
/* Limit the stack walk to avoid referencing undefined memory */ |
if((uintptr_t)next_frame_pointer <= (uintptr_t)frame_pointer || |
(uintptr_t)next_frame_pointer > (uintptr_t)frame_pointer + 64*1024) |
break; |
frame_pointer = next_frame_pointer; |
} |
#else |
(void) frame_pointer; |
#endif |
while(nr_frames) { |
backtrace[i++].function = NULL; |
--nr_frames; |
} |
} |
void |
debug_backtrace_dump(const struct debug_stack_frame *backtrace, |
unsigned nr_frames) |
{ |
unsigned i; |
for(i = 0; i < nr_frames; ++i) { |
if(!backtrace[i].function) |
break; |
debug_symbol_print(backtrace[i].function); |
} |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_debug_stack.h |
---|
0,0 → 1,72 |
/************************************************************************** |
* |
* Copyright 2009 VMware, Inc. |
* 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 VMWARE 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_DEBUG_STACK_H_ |
#define U_DEBUG_STACK_H_ |
/** |
* @file |
* Stack backtracing. |
* |
* @author Jose Fonseca <jfonseca@vmware.com> |
*/ |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* Represent a frame from a stack backtrace. |
* |
* XXX: Do not change this. |
* |
* TODO: This should be refactored as a void * typedef. |
*/ |
struct debug_stack_frame |
{ |
const void *function; |
}; |
void |
debug_backtrace_capture(struct debug_stack_frame *backtrace, |
unsigned start_frame, |
unsigned nr_frames); |
void |
debug_backtrace_dump(const struct debug_stack_frame *backtrace, |
unsigned nr_frames); |
#ifdef __cplusplus |
} |
#endif |
#endif /* U_DEBUG_STACK_H_ */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_debug_symbol.c |
---|
0,0 → 1,326 |
/************************************************************************** |
* |
* Copyright 2009 VMware, Inc. |
* 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 VMWARE 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. |
* |
**************************************************************************/ |
/** |
* @file |
* Symbol lookup. |
* |
* @author Jose Fonseca <jfonseca@vmware.com> |
*/ |
#include "pipe/p_compiler.h" |
#include "os/os_thread.h" |
#include "u_string.h" |
#include "u_debug.h" |
#include "u_debug_symbol.h" |
#include "u_hash_table.h" |
#if defined(PIPE_OS_WINDOWS) |
#include <windows.h> |
#include <stddef.h> |
#include "dbghelp.h" |
/** |
* SymInitialize() must be called once for each process (in this case, the |
* current process), before any of the other functions can be called. |
*/ |
static BOOL g_bSymInitialized = FALSE; |
/** |
* Lookup the address of a DbgHelp function. |
*/ |
static FARPROC WINAPI |
getDbgHelpProcAddress(LPCSTR lpProcName) |
{ |
static HMODULE hModule = NULL; |
if (!hModule) { |
static boolean bail = FALSE; |
if (bail) { |
return NULL; |
} |
#ifdef PIPE_CC_GCC |
/* |
* DbgHelp does not understand the debug information generated by MinGW toolchain. |
* |
* mgwhelp.dll is a dbghelp.dll look-alike replacement, which is able to |
* understand MinGW symbols, including on 64-bit builds. |
*/ |
if (!hModule) { |
hModule = LoadLibraryA("mgwhelp.dll"); |
if (!hModule) { |
_debug_printf("warning: mgwhelp.dll not found: symbol names will not be resolved\n" |
"warning: download it from http://code.google.com/p/jrfonseca/wiki/DrMingw#MgwHelp\n"); |
} |
} |
/* |
* bfdhelp.dll was the predecessor of mgwhelp.dll. It is available from |
* http://people.freedesktop.org/~jrfonseca/bfdhelp/ for now. |
*/ |
if (!hModule) { |
hModule = LoadLibraryA("bfdhelp.dll"); |
} |
#endif |
/* |
* Fallback to the real DbgHelp. |
*/ |
if (!hModule) { |
hModule = LoadLibraryA("dbghelp.dll"); |
} |
if (!hModule) { |
bail = TRUE; |
return NULL; |
} |
} |
return GetProcAddress(hModule, lpProcName); |
} |
/** |
* Generic macro to dispatch a DbgHelp functions. |
*/ |
#define DBGHELP_DISPATCH(_name, _ret_type, _ret_default, _arg_types, _arg_names) \ |
static _ret_type WINAPI \ |
j_##_name _arg_types \ |
{ \ |
typedef BOOL (WINAPI *PFN) _arg_types; \ |
static PFN pfn = NULL; \ |
if (!pfn) { \ |
pfn = (PFN) getDbgHelpProcAddress(#_name); \ |
if (!pfn) { \ |
return _ret_default; \ |
} \ |
} \ |
return pfn _arg_names; \ |
} |
DBGHELP_DISPATCH(SymInitialize, |
BOOL, 0, |
(HANDLE hProcess, PSTR UserSearchPath, BOOL fInvadeProcess), |
(hProcess, UserSearchPath, fInvadeProcess)) |
DBGHELP_DISPATCH(SymSetOptions, |
DWORD, FALSE, |
(DWORD SymOptions), |
(SymOptions)) |
DBGHELP_DISPATCH(SymFromAddr, |
BOOL, FALSE, |
(HANDLE hProcess, DWORD64 Address, PDWORD64 Displacement, PSYMBOL_INFO Symbol), |
(hProcess, Address, Displacement, Symbol)) |
DBGHELP_DISPATCH(SymGetLineFromAddr64, |
BOOL, FALSE, |
(HANDLE hProcess, DWORD64 dwAddr, PDWORD pdwDisplacement, PIMAGEHLP_LINE64 Line), |
(hProcess, dwAddr, pdwDisplacement, Line)) |
#undef DBGHELP_DISPATCH |
static INLINE boolean |
debug_symbol_name_dbghelp(const void *addr, char* buf, unsigned size) |
{ |
DWORD64 dwAddr = (DWORD64)(uintptr_t)addr; |
HANDLE hProcess = GetCurrentProcess(); |
/* General purpose buffer, to back pSymbol and other temporary stuff. |
* Must not be too memory hungry here to avoid stack overflows. |
*/ |
CHAR buffer[512]; |
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO) buffer; |
DWORD64 dwDisplacement = 0; /* Displacement of the input address, relative to the start of the symbol */ |
DWORD dwLineDisplacement = 0; |
IMAGEHLP_LINE64 Line; |
memset(pSymbol, 0, sizeof *pSymbol); |
pSymbol->SizeOfStruct = sizeof buffer; |
pSymbol->MaxNameLen = sizeof buffer - offsetof(SYMBOL_INFO, Name); |
if (!g_bSymInitialized) { |
j_SymSetOptions(/* SYMOPT_UNDNAME | */ SYMOPT_LOAD_LINES); |
if (j_SymInitialize(hProcess, NULL, TRUE)) { |
g_bSymInitialized = TRUE; |
} |
} |
/* Lookup symbol name */ |
if (!g_bSymInitialized || |
!j_SymFromAddr(hProcess, dwAddr, &dwDisplacement, pSymbol)) { |
/* |
* We couldn't obtain symbol information. At least tell which module the address belongs. |
*/ |
HMODULE hModule = NULL; |
if (!GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, |
(LPCTSTR)addr, |
&hModule)) { |
return FALSE; |
} |
if (GetModuleFileNameA(hModule, buffer, sizeof buffer) == sizeof buffer) { |
return FALSE; |
} |
util_snprintf(buf, size, "%p at %s+0x%lx", |
addr, buffer, |
(unsigned long)((uintptr_t)addr - (uintptr_t)hModule)); |
return TRUE; |
} |
/* |
* Try to get filename and line number. |
*/ |
memset(&Line, 0, sizeof Line); |
Line.SizeOfStruct = sizeof Line; |
if (!j_SymGetLineFromAddr64(hProcess, dwAddr, &dwLineDisplacement, &Line)) { |
Line.FileName = NULL; |
} |
if (Line.FileName) { |
util_snprintf(buf, size, "%s at %s:%lu", pSymbol->Name, Line.FileName, Line.LineNumber); |
} else { |
util_snprintf(buf, size, "%s", pSymbol->Name); |
} |
return TRUE; |
} |
#endif /* PIPE_OS_WINDOWS */ |
#if defined(__GLIBC__) && !defined(__UCLIBC__) |
#include <execinfo.h> |
/* This can only provide dynamic symbols, or binary offsets into a file. |
* |
* To fix this, post-process the output with tools/addr2line.sh |
*/ |
static INLINE boolean |
debug_symbol_name_glibc(const void *addr, char* buf, unsigned size) |
{ |
char** syms = backtrace_symbols((void**)&addr, 1); |
if (!syms) { |
return FALSE; |
} |
strncpy(buf, syms[0], size); |
buf[size - 1] = 0; |
free(syms); |
return TRUE; |
} |
#endif /* defined(__GLIBC__) && !defined(__UCLIBC__) */ |
void |
debug_symbol_name(const void *addr, char* buf, unsigned size) |
{ |
#if defined(PIPE_OS_WINDOWS) |
if (debug_symbol_name_dbghelp(addr, buf, size)) { |
return; |
} |
#endif |
#if defined(__GLIBC__) && !defined(__UCLIBC__) |
if (debug_symbol_name_glibc(addr, buf, size)) { |
return; |
} |
#endif |
util_snprintf(buf, size, "%p", addr); |
buf[size - 1] = 0; |
} |
void |
debug_symbol_print(const void *addr) |
{ |
char buf[1024]; |
debug_symbol_name(addr, buf, sizeof(buf)); |
debug_printf("\t%s\n", buf); |
} |
struct util_hash_table* symbols_hash; |
pipe_static_mutex(symbols_mutex); |
static unsigned hash_ptr(void* p) |
{ |
return (unsigned)(uintptr_t)p; |
} |
static int compare_ptr(void* a, void* b) |
{ |
if(a == b) |
return 0; |
else if(a < b) |
return -1; |
else |
return 1; |
} |
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); |
name = util_hash_table_get(symbols_hash, (void*)addr); |
if(!name) |
{ |
char buf[1024]; |
debug_symbol_name(addr, buf, sizeof(buf)); |
name = strdup(buf); |
util_hash_table_set(symbols_hash, (void*)addr, (void*)name); |
} |
pipe_mutex_unlock(symbols_mutex); |
return name; |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_debug_symbol.h |
---|
0,0 → 1,58 |
/************************************************************************** |
* |
* Copyright 2009 VMware, Inc. |
* 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 VMWARE 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_DEBUG_SYMBOL_H_ |
#define U_DEBUG_SYMBOL_H_ |
/** |
* @file |
* Symbol lookup. |
* |
* @author Jose Fonseca <jfonseca@vmware.com> |
*/ |
#ifdef __cplusplus |
extern "C" { |
#endif |
void |
debug_symbol_name(const void *addr, char* buf, unsigned size); |
const char* |
debug_symbol_name_cached(const void *addr); |
void |
debug_symbol_print(const void *addr); |
#ifdef __cplusplus |
} |
#endif |
#endif /* U_DEBUG_SYMBOL_H_ */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_dirty_flags.h |
---|
0,0 → 1,32 |
#ifndef U_DIRTY_FLAGS_H |
#define U_DIRTY_FLAGS_H |
/* Here's a convenient list of dirty flags to use in a driver. Either |
* include it directly or use it as a starting point for your own |
* list. |
*/ |
#define U_NEW_VIEWPORT 0x1 |
#define U_NEW_RASTERIZER 0x2 |
#define U_NEW_FS 0x4 |
#define U_NEW_FS_CONSTANTS 0x8 |
#define U_NEW_FS_SAMPLER_VIEW 0x10 |
#define U_NEW_FS_SAMPLER_STATES 0x20 |
#define U_NEW_VS 0x40 |
#define U_NEW_VS_CONSTANTS 0x80 |
#define U_NEW_VS_SAMPLER_VIEW 0x100 |
#define U_NEW_VS_SAMPLER_STATES 0x200 |
#define U_NEW_BLEND 0x400 |
#define U_NEW_CLIP 0x800 |
#define U_NEW_SCISSOR 0x1000 |
#define U_NEW_POLYGON_STIPPLE 0x2000 |
#define U_NEW_FRAMEBUFFER 0x4000 |
#define U_NEW_VERTEX_ELEMENTS 0x8000 |
#define U_NEW_VERTEX_BUFFER 0x10000 |
#define U_NEW_QUERY 0x20000 |
#define U_NEW_DEPTH_STENCIL 0x40000 |
#define U_NEW_GS 0x80000 |
#define U_NEW_GS_CONSTANTS 0x100000 |
#define U_NEW_GS_SAMPLER_VIEW 0x200000 |
#define U_NEW_GS_SAMPLER_STATES 0x400000 |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_dirty_surfaces.h |
---|
0,0 → 1,119 |
/************************************************************************** |
* |
* Copyright 2010 Luca Barbieri |
* |
* 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, sublicense, 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 NONINFRINGEMENT. |
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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_DIRTY_SURFACES_H_ |
#define U_DIRTY_SURFACES_H_ |
#include "pipe/p_state.h" |
#include "util/u_double_list.h" |
#include "util/u_math.h" |
struct pipe_context; |
typedef void (*util_dirty_surface_flush_t) (struct pipe_context *, struct pipe_surface *); |
struct util_dirty_surfaces |
{ |
struct list_head dirty_list; |
}; |
struct util_dirty_surface |
{ |
struct pipe_surface base; |
struct list_head dirty_list; |
}; |
static INLINE void |
util_dirty_surfaces_init(struct util_dirty_surfaces *ds) |
{ |
LIST_INITHEAD(&ds->dirty_list); |
} |
static INLINE void |
util_dirty_surfaces_use_for_sampling(struct pipe_context *pipe, struct util_dirty_surfaces *dss, util_dirty_surface_flush_t flush) |
{ |
struct list_head *p, *next; |
for(p = dss->dirty_list.next; p != &dss->dirty_list; p = next) |
{ |
struct util_dirty_surface *ds = LIST_ENTRY(struct util_dirty_surface, p, dirty_list); |
next = p->next; |
flush(pipe, &ds->base); |
} |
} |
static INLINE void |
util_dirty_surfaces_use_levels_for_sampling(struct pipe_context *pipe, struct util_dirty_surfaces *dss, unsigned first, unsigned last, util_dirty_surface_flush_t flush) |
{ |
struct list_head *p, *next; |
if(first > last) |
return; |
for(p = dss->dirty_list.next; p != &dss->dirty_list; p = next) |
{ |
struct util_dirty_surface *ds = LIST_ENTRY(struct util_dirty_surface, p, dirty_list); |
next = p->next; |
if(ds->base.u.tex.level >= first && ds->base.u.tex.level <= last) |
flush(pipe, &ds->base); |
} |
} |
static INLINE void |
util_dirty_surfaces_use_for_sampling_with(struct pipe_context *pipe, struct util_dirty_surfaces *dss, struct pipe_sampler_view *psv, struct pipe_sampler_state *pss, util_dirty_surface_flush_t flush) |
{ |
if(!LIST_IS_EMPTY(&dss->dirty_list)) |
util_dirty_surfaces_use_levels_for_sampling(pipe, dss, (unsigned)pss->min_lod + psv->u.tex.first_level, |
MIN2((unsigned)ceilf(pss->max_lod) + psv->u.tex.first_level, psv->u.tex.last_level), flush); |
} |
static INLINE void |
util_dirty_surface_init(struct util_dirty_surface *ds) |
{ |
LIST_INITHEAD(&ds->dirty_list); |
} |
static INLINE boolean |
util_dirty_surface_is_dirty(struct util_dirty_surface *ds) |
{ |
return !LIST_IS_EMPTY(&ds->dirty_list); |
} |
static INLINE void |
util_dirty_surface_set_dirty(struct util_dirty_surfaces *dss, struct util_dirty_surface *ds) |
{ |
if(LIST_IS_EMPTY(&ds->dirty_list)) |
LIST_ADDTAIL(&ds->dirty_list, &dss->dirty_list); |
} |
static INLINE void |
util_dirty_surface_set_clean(struct util_dirty_surfaces *dss, struct util_dirty_surface *ds) |
{ |
if(!LIST_IS_EMPTY(&ds->dirty_list)) |
LIST_DELINIT(&ds->dirty_list); |
} |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_dl.c |
---|
0,0 → 1,94 |
/************************************************************************** |
* |
* Copyright 2009 VMware, Inc. |
* Copyright 1999-2008 Brian Paul |
* 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 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 |
* THE COPYRIGHT HOLDERS, 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. |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
**************************************************************************/ |
#include "pipe/p_config.h" |
#include "pipe/p_compiler.h" |
#if defined(PIPE_OS_UNIX) |
#include <dlfcn.h> |
#endif |
#if defined(PIPE_OS_WINDOWS) |
#include <windows.h> |
#endif |
#include "u_dl.h" |
#include "u_pointer.h" |
struct util_dl_library * |
util_dl_open(const char *filename) |
{ |
#if defined(PIPE_OS_UNIX) |
return (struct util_dl_library *)dlopen(filename, RTLD_LAZY | RTLD_GLOBAL); |
#elif defined(PIPE_OS_WINDOWS) |
return (struct util_dl_library *)LoadLibraryA(filename); |
#else |
return NULL; |
#endif |
} |
util_dl_proc |
util_dl_get_proc_address(struct util_dl_library *library, |
const char *procname) |
{ |
#if defined(PIPE_OS_UNIX) |
return (util_dl_proc) pointer_to_func(dlsym((void *)library, procname)); |
#elif defined(PIPE_OS_WINDOWS) |
return (util_dl_proc)GetProcAddress((HMODULE)library, procname); |
#else |
return (util_dl_proc)NULL; |
#endif |
} |
void |
util_dl_close(struct util_dl_library *library) |
{ |
#if defined(PIPE_OS_UNIX) |
dlclose((void *)library); |
#elif defined(PIPE_OS_WINDOWS) |
FreeLibrary((HMODULE)library); |
#else |
(void)library; |
#endif |
} |
const char * |
util_dl_error(void) |
{ |
#if defined(PIPE_OS_UNIX) |
return dlerror(); |
#elif defined(PIPE_OS_WINDOWS) |
return "unknown error"; |
#else |
return "unknown error"; |
#endif |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_dl.h |
---|
0,0 → 1,83 |
/************************************************************************** |
* |
* Copyright 2009 VMware, Inc. |
* 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 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 |
* THE COPYRIGHT HOLDERS, 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. |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
**************************************************************************/ |
#ifndef U_DL_H_ |
#define U_DL_H_ |
#include "pipe/p_config.h" |
#if defined(PIPE_OS_WINDOWS) |
# define UTIL_DL_EXT ".dll" |
# define UTIL_DL_PREFIX "" |
#elif defined(PIPE_OS_APPLE) |
# define UTIL_DL_EXT ".dylib" |
# define UTIL_DL_PREFIX "lib" |
#else |
# define UTIL_DL_EXT ".so" |
# define UTIL_DL_PREFIX "lib" |
#endif |
struct util_dl_library; |
typedef void (*util_dl_proc)(void); |
/** |
* Open a library dynamically. |
*/ |
struct util_dl_library * |
util_dl_open(const char *filename); |
/** |
* Lookup a function in a library. |
*/ |
util_dl_proc |
util_dl_get_proc_address(struct util_dl_library *library, |
const char *procname); |
/** |
* Close a library. |
*/ |
void |
util_dl_close(struct util_dl_library *library); |
/** |
* Return most recent error message. |
*/ |
const char * |
util_dl_error(void); |
#endif /* U_DL_H_ */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_double_list.h |
---|
0,0 → 1,147 |
/************************************************************************** |
* |
* Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA. |
* 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 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 |
* THE COPYRIGHT HOLDERS, 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. |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
**************************************************************************/ |
/** |
* \file |
* List macros heavily inspired by the Linux kernel |
* list handling. No list looping yet. |
* |
* Is not threadsafe, so common operations need to |
* be protected using an external mutex. |
*/ |
#ifndef _U_DOUBLE_LIST_H_ |
#define _U_DOUBLE_LIST_H_ |
#include <stddef.h> |
#include "pipe/p_compiler.h" |
struct list_head |
{ |
struct list_head *prev; |
struct list_head *next; |
}; |
static INLINE void list_inithead(struct list_head *item) |
{ |
item->prev = item; |
item->next = item; |
} |
static INLINE void list_add(struct list_head *item, struct list_head *list) |
{ |
item->prev = list; |
item->next = list->next; |
list->next->prev = item; |
list->next = item; |
} |
static INLINE void list_addtail(struct list_head *item, struct list_head *list) |
{ |
item->next = list; |
item->prev = list->prev; |
list->prev->next = item; |
list->prev = item; |
} |
static INLINE void list_replace(struct list_head *from, struct list_head *to) |
{ |
to->prev = from->prev; |
to->next = from->next; |
from->next->prev = to; |
from->prev->next = to; |
} |
static INLINE void list_del(struct list_head *item) |
{ |
item->prev->next = item->next; |
item->next->prev = item->prev; |
item->prev = item->next = NULL; |
} |
static INLINE void list_delinit(struct list_head *item) |
{ |
item->prev->next = item->next; |
item->next->prev = item->prev; |
item->next = item; |
item->prev = item; |
} |
#define LIST_INITHEAD(__item) list_inithead(__item) |
#define LIST_ADD(__item, __list) list_add(__item, __list) |
#define LIST_ADDTAIL(__item, __list) list_addtail(__item, __list) |
#define LIST_REPLACE(__from, __to) list_replace(__from, __to) |
#define LIST_DEL(__item) list_del(__item) |
#define LIST_DELINIT(__item) list_delinit(__item) |
#define LIST_ENTRY(__type, __item, __field) \ |
((__type *)(((char *)(__item)) - offsetof(__type, __field))) |
#define LIST_IS_EMPTY(__list) \ |
((__list)->next == (__list)) |
/** |
* Cast from a pointer to a member of a struct back to the containing struct. |
* |
* 'sample' MUST be initialized, or else the result is undefined! |
*/ |
#ifndef container_of |
#define container_of(ptr, sample, member) \ |
(void *)((char *)(ptr) \ |
- ((char *)&(sample)->member - (char *)(sample))) |
#endif |
#define LIST_FOR_EACH_ENTRY(pos, head, member) \ |
for (pos = NULL, pos = container_of((head)->next, pos, member); \ |
&pos->member != (head); \ |
pos = container_of(pos->member.next, pos, member)) |
#define LIST_FOR_EACH_ENTRY_SAFE(pos, storage, head, member) \ |
for (pos = NULL, pos = container_of((head)->next, pos, member), \ |
storage = container_of(pos->member.next, pos, member); \ |
&pos->member != (head); \ |
pos = storage, storage = container_of(storage->member.next, storage, member)) |
#define LIST_FOR_EACH_ENTRY_SAFE_REV(pos, storage, head, member) \ |
for (pos = NULL, pos = container_of((head)->prev, pos, member), \ |
storage = container_of(pos->member.prev, pos, member); \ |
&pos->member != (head); \ |
pos = storage, storage = container_of(storage->member.prev, storage, member)) |
#define LIST_FOR_EACH_ENTRY_FROM(pos, start, head, member) \ |
for (pos = NULL, pos = container_of((start), pos, member); \ |
&pos->member != (head); \ |
pos = container_of(pos->member.next, pos, member)) |
#define LIST_FOR_EACH_ENTRY_FROM_REV(pos, start, head, member) \ |
for (pos = NULL, pos = container_of((start), pos, member); \ |
&pos->member != (head); \ |
pos = container_of(pos->member.prev, pos, member)) |
#endif /*_U_DOUBLE_LIST_H_*/ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_draw.c |
---|
0,0 → 1,125 |
/************************************************************************** |
* |
* Copyright 2011 VMware, Inc. |
* 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 VMWARE 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_debug.h" |
#include "util/u_math.h" |
#include "util/u_format.h" |
#include "util/u_draw.h" |
/** |
* Returns the largest legal index value plus one for the current set |
* of bound vertex buffers. Regardless of any other consideration, |
* all vertex lookups need to be clamped to 0..max_index-1 to prevent |
* an out-of-bound access. |
* |
* Note that if zero is returned it means that one or more buffers is |
* too small to contain any valid vertex data. |
*/ |
unsigned |
util_draw_max_index( |
const struct pipe_vertex_buffer *vertex_buffers, |
const struct pipe_vertex_element *vertex_elements, |
unsigned nr_vertex_elements, |
const struct pipe_draw_info *info) |
{ |
unsigned max_index; |
unsigned i; |
max_index = ~0U - 1; |
for (i = 0; i < nr_vertex_elements; i++) { |
const struct pipe_vertex_element *element = |
&vertex_elements[i]; |
const struct pipe_vertex_buffer *buffer = |
&vertex_buffers[element->vertex_buffer_index]; |
unsigned buffer_size; |
const struct util_format_description *format_desc; |
unsigned format_size; |
if (!buffer->buffer) { |
continue; |
} |
assert(buffer->buffer->height0 == 1); |
assert(buffer->buffer->depth0 == 1); |
buffer_size = buffer->buffer->width0; |
format_desc = util_format_description(element->src_format); |
assert(format_desc->block.width == 1); |
assert(format_desc->block.height == 1); |
assert(format_desc->block.bits % 8 == 0); |
format_size = format_desc->block.bits/8; |
if (buffer->buffer_offset >= buffer_size) { |
/* buffer is too small */ |
return 0; |
} |
buffer_size -= buffer->buffer_offset; |
if (element->src_offset >= buffer_size) { |
/* buffer is too small */ |
return 0; |
} |
buffer_size -= element->src_offset; |
if (format_size > buffer_size) { |
/* buffer is too small */ |
return 0; |
} |
buffer_size -= format_size; |
if (buffer->stride != 0) { |
unsigned buffer_max_index; |
buffer_max_index = buffer_size / buffer->stride; |
if (element->instance_divisor == 0) { |
/* Per-vertex data */ |
max_index = MIN2(max_index, buffer_max_index); |
} |
else { |
/* Per-instance data. Simply make sure the state tracker didn't |
* request more instances than those that fit in the buffer */ |
if ((info->start_instance + info->instance_count)/element->instance_divisor |
> (buffer_max_index + 1)) { |
/* FIXME: We really should stop thinking in terms of maximum |
* indices/instances and simply start clamping against buffer |
* size. */ |
debug_printf("%s: too many instances for vertex buffer\n", |
__FUNCTION__); |
return 0; |
} |
} |
} |
} |
return max_index + 1; |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_draw.h |
---|
0,0 → 1,157 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* 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 TUNGSTEN GRAPHICS 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_DRAW_H |
#define U_DRAW_H |
#include "pipe/p_compiler.h" |
#include "pipe/p_context.h" |
#include "pipe/p_state.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
static INLINE void |
util_draw_init_info(struct pipe_draw_info *info) |
{ |
memset(info, 0, sizeof(*info)); |
info->instance_count = 1; |
info->max_index = 0xffffffff; |
} |
static INLINE void |
util_draw_arrays(struct pipe_context *pipe, uint mode, uint start, uint count) |
{ |
struct pipe_draw_info info; |
util_draw_init_info(&info); |
info.mode = mode; |
info.start = start; |
info.count = count; |
info.min_index = start; |
info.max_index = start + count - 1; |
pipe->draw_vbo(pipe, &info); |
} |
static INLINE void |
util_draw_elements(struct pipe_context *pipe, int index_bias, |
uint mode, uint start, uint count) |
{ |
struct pipe_draw_info info; |
util_draw_init_info(&info); |
info.indexed = TRUE; |
info.mode = mode; |
info.start = start; |
info.count = count; |
info.index_bias = index_bias; |
pipe->draw_vbo(pipe, &info); |
} |
static INLINE void |
util_draw_arrays_instanced(struct pipe_context *pipe, |
uint mode, uint start, uint count, |
uint start_instance, |
uint instance_count) |
{ |
struct pipe_draw_info info; |
util_draw_init_info(&info); |
info.mode = mode; |
info.start = start; |
info.count = count; |
info.start_instance = start_instance; |
info.instance_count = instance_count; |
info.min_index = start; |
info.max_index = start + count - 1; |
pipe->draw_vbo(pipe, &info); |
} |
static INLINE void |
util_draw_elements_instanced(struct pipe_context *pipe, |
int index_bias, |
uint mode, uint start, uint count, |
uint start_instance, |
uint instance_count) |
{ |
struct pipe_draw_info info; |
util_draw_init_info(&info); |
info.indexed = TRUE; |
info.mode = mode; |
info.start = start; |
info.count = count; |
info.index_bias = index_bias; |
info.start_instance = start_instance; |
info.instance_count = instance_count; |
pipe->draw_vbo(pipe, &info); |
} |
static INLINE void |
util_draw_range_elements(struct pipe_context *pipe, |
int index_bias, |
uint min_index, |
uint max_index, |
uint mode, uint start, uint count) |
{ |
struct pipe_draw_info info; |
util_draw_init_info(&info); |
info.indexed = TRUE; |
info.mode = mode; |
info.start = start; |
info.count = count; |
info.index_bias = index_bias; |
info.min_index = min_index; |
info.max_index = max_index; |
pipe->draw_vbo(pipe, &info); |
} |
unsigned |
util_draw_max_index( |
const struct pipe_vertex_buffer *vertex_buffers, |
const struct pipe_vertex_element *vertex_elements, |
unsigned nr_vertex_elements, |
const struct pipe_draw_info *info); |
#ifdef __cplusplus |
} |
#endif |
#endif /* !U_DRAW_H */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_draw_quad.c |
---|
0,0 → 1,158 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* 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 TUNGSTEN GRAPHICS 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 "pipe/p_context.h" |
#include "pipe/p_defines.h" |
#include "util/u_inlines.h" |
#include "util/u_draw_quad.h" |
#include "util/u_memory.h" |
#include "cso_cache/cso_context.h" |
/** |
* Draw a simple vertex buffer / primitive. |
* Limited to float[4] vertex attribs, tightly packed. |
*/ |
void |
util_draw_vertex_buffer(struct pipe_context *pipe, |
struct cso_context *cso, |
struct pipe_resource *vbuf, |
uint vbuf_slot, |
uint offset, |
uint prim_type, |
uint num_verts, |
uint num_attribs) |
{ |
struct pipe_vertex_buffer vbuffer; |
assert(num_attribs <= PIPE_MAX_ATTRIBS); |
/* tell pipe about the vertex buffer */ |
memset(&vbuffer, 0, sizeof(vbuffer)); |
vbuffer.buffer = vbuf; |
vbuffer.stride = num_attribs * 4 * sizeof(float); /* vertex size */ |
vbuffer.buffer_offset = offset; |
/* note: vertex elements already set by caller */ |
if (cso) { |
cso_set_vertex_buffers(cso, vbuf_slot, 1, &vbuffer); |
cso_draw_arrays(cso, prim_type, 0, num_verts); |
} else { |
pipe->set_vertex_buffers(pipe, vbuf_slot, 1, &vbuffer); |
util_draw_arrays(pipe, prim_type, 0, num_verts); |
} |
} |
/** |
* Draw a simple vertex buffer / primitive. |
* Limited to float[4] vertex attribs, tightly packed. |
*/ |
void |
util_draw_user_vertex_buffer(struct cso_context *cso, void *buffer, |
uint prim_type, uint num_verts, uint num_attribs) |
{ |
struct pipe_vertex_buffer vbuffer = {0}; |
assert(num_attribs <= PIPE_MAX_ATTRIBS); |
vbuffer.user_buffer = buffer; |
vbuffer.stride = num_attribs * 4 * sizeof(float); /* vertex size */ |
/* note: vertex elements already set by caller */ |
cso_set_vertex_buffers(cso, 0, 1, &vbuffer); |
cso_draw_arrays(cso, prim_type, 0, num_verts); |
} |
/** |
* Draw screen-aligned textured quad. |
* Note: this isn't especially efficient. |
*/ |
void |
util_draw_texquad(struct pipe_context *pipe, struct cso_context *cso, |
uint vbuf_slot, |
float x0, float y0, float x1, float y1, float z) |
{ |
uint numAttribs = 2, i, j; |
uint vertexBytes = 4 * (4 * numAttribs * sizeof(float)); |
struct pipe_resource *vbuf = NULL; |
float *v = NULL; |
v = MALLOC(vertexBytes); |
if (v == NULL) |
goto out; |
/* |
* Load vertex buffer |
*/ |
for (i = j = 0; i < 4; i++) { |
v[j + 2] = z; /* z */ |
v[j + 3] = 1.0; /* w */ |
v[j + 6] = 0.0; /* r */ |
v[j + 7] = 1.0; /* q */ |
j += 8; |
} |
v[0] = x0; |
v[1] = y0; |
v[4] = 0.0; /*s*/ |
v[5] = 0.0; /*t*/ |
v[8] = x1; |
v[9] = y0; |
v[12] = 1.0; |
v[13] = 0.0; |
v[16] = x1; |
v[17] = y1; |
v[20] = 1.0; |
v[21] = 1.0; |
v[24] = x0; |
v[25] = y1; |
v[28] = 0.0; |
v[29] = 1.0; |
vbuf = pipe_buffer_create(pipe->screen, PIPE_BIND_VERTEX_BUFFER, |
PIPE_USAGE_STAGING, vertexBytes); |
if (!vbuf) |
goto out; |
pipe_buffer_write(pipe, vbuf, 0, vertexBytes, v); |
util_draw_vertex_buffer(pipe, cso, vbuf, vbuf_slot, 0, |
PIPE_PRIM_TRIANGLE_FAN, 4, 2); |
out: |
if (vbuf) |
pipe_resource_reference(&vbuf, NULL); |
FREE(v); |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_draw_quad.h |
---|
0,0 → 1,66 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* 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 TUNGSTEN GRAPHICS 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_DRAWQUAD_H |
#define U_DRAWQUAD_H |
#include "pipe/p_compiler.h" |
#include "pipe/p_context.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
struct pipe_resource; |
struct cso_context; |
#include "util/u_draw.h" |
extern void |
util_draw_vertex_buffer(struct pipe_context *pipe, struct cso_context *cso, |
struct pipe_resource *vbuf, uint vbuf_slot, |
uint offset, uint prim_type, uint num_attribs, |
uint num_verts); |
void |
util_draw_user_vertex_buffer(struct cso_context *cso, void *buffer, |
uint prim_type, uint num_verts, uint num_attribs); |
extern void |
util_draw_texquad(struct pipe_context *pipe, struct cso_context *cso, |
uint vbuf_slot, |
float x0, float y0, float x1, float y1, float z); |
#ifdef __cplusplus |
} |
#endif |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_dual_blend.h |
---|
0,0 → 1,26 |
#ifndef U_DUAL_BLEND_H |
#define U_DUAL_BLEND_H |
#include "pipe/p_state.h" |
static INLINE boolean util_blend_factor_is_dual_src(int factor) |
{ |
return (factor == PIPE_BLENDFACTOR_SRC1_COLOR) || |
(factor == PIPE_BLENDFACTOR_SRC1_ALPHA) || |
(factor == PIPE_BLENDFACTOR_INV_SRC1_COLOR) || |
(factor == PIPE_BLENDFACTOR_INV_SRC1_ALPHA); |
} |
static INLINE boolean util_blend_state_is_dual(const struct pipe_blend_state *blend, |
int index) |
{ |
if (util_blend_factor_is_dual_src(blend->rt[index].rgb_src_factor) || |
util_blend_factor_is_dual_src(blend->rt[index].alpha_src_factor) || |
util_blend_factor_is_dual_src(blend->rt[index].rgb_dst_factor) || |
util_blend_factor_is_dual_src(blend->rt[index].alpha_dst_factor)) |
return true; |
return false; |
} |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_dump.h |
---|
0,0 → 1,181 |
/************************************************************************** |
* |
* Copyright 2009 VMware, Inc. |
* 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 VMWARE 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. |
* |
**************************************************************************/ |
/** |
* @file |
* Dump data in human/machine readable format. |
* |
* @author Jose Fonseca <jfonseca@vmware.com> |
*/ |
#ifndef U_DEBUG_DUMP_H_ |
#define U_DEBUG_DUMP_H_ |
#include "pipe/p_compiler.h" |
#include "pipe/p_state.h" |
#include <stdio.h> |
#ifdef __cplusplus |
extern "C" { |
#endif |
#define UTIL_DUMP_INVALID_NAME "<invalid>" |
/* |
* p_defines.h |
* |
* XXX: These functions don't really dump anything -- just translate into |
* strings so a verb better than "dump" should be used instead, in order to |
* free up the namespace to the true dumper functions. |
*/ |
const char * |
util_dump_blend_factor(unsigned value, boolean shortened); |
const char * |
util_dump_blend_func(unsigned value, boolean shortened); |
const char * |
util_dump_logicop(unsigned value, boolean shortened); |
const char * |
util_dump_func(unsigned value, boolean shortened); |
const char * |
util_dump_stencil_op(unsigned value, boolean shortened); |
const char * |
util_dump_tex_target(unsigned value, boolean shortened); |
const char * |
util_dump_tex_wrap(unsigned value, boolean shortened); |
const char * |
util_dump_tex_mipfilter(unsigned value, boolean shortened); |
const char * |
util_dump_tex_filter(unsigned value, boolean shortened); |
/* |
* p_state.h, through a FILE |
*/ |
void |
util_dump_template(FILE *stream, |
const struct pipe_resource *templat); |
void |
util_dump_rasterizer_state(FILE *stream, |
const struct pipe_rasterizer_state *state); |
void |
util_dump_poly_stipple(FILE *stream, |
const struct pipe_poly_stipple *state); |
void |
util_dump_viewport_state(FILE *stream, |
const struct pipe_viewport_state *state); |
void |
util_dump_scissor_state(FILE *stream, |
const struct pipe_scissor_state *state); |
void |
util_dump_clip_state(FILE *stream, |
const struct pipe_clip_state *state); |
void |
util_dump_shader_state(FILE *stream, |
const struct pipe_shader_state *state); |
void |
util_dump_depth_stencil_alpha_state(FILE *stream, |
const struct pipe_depth_stencil_alpha_state *state); |
void |
util_dump_rt_blend_state(FILE *stream, |
const struct pipe_rt_blend_state *state); |
void |
util_dump_blend_state(FILE *stream, |
const struct pipe_blend_state *state); |
void |
util_dump_blend_color(FILE *stream, |
const struct pipe_blend_color *state); |
void |
util_dump_stencil_ref(FILE *stream, |
const struct pipe_stencil_ref *state); |
void |
util_dump_framebuffer_state(FILE *stream, |
const struct pipe_framebuffer_state *state); |
void |
util_dump_sampler_state(FILE *stream, |
const struct pipe_sampler_state *state); |
void |
util_dump_surface(FILE *stream, |
const struct pipe_surface *state); |
void |
util_dump_transfer(FILE *stream, |
const struct pipe_transfer *state); |
void |
util_dump_vertex_buffer(FILE *stream, |
const struct pipe_vertex_buffer *state); |
void |
util_dump_vertex_element(FILE *stream, |
const struct pipe_vertex_element *state); |
void |
util_dump_draw_info(FILE *stream, const struct pipe_draw_info *state); |
void |
util_dump_box(FILE *stream, const struct pipe_box *box); |
void |
util_dump_blit_info(FILE *stream, const struct pipe_blit_info *info); |
/* FIXME: Move the other debug_dump_xxx functions out of u_debug.h into here. */ |
#ifdef __cplusplus |
} |
#endif |
#endif /* U_DEBUG_H_ */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_dump_defines.c |
---|
0,0 → 1,361 |
/************************************************************************** |
* |
* Copyright 2009 VMware, Inc. |
* 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 VMWARE 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_memory.h" |
#include "util/u_debug.h" |
#include "util/u_dump.h" |
#if 0 |
static const char * |
util_dump_strip_prefix(const char *name, |
const char *prefix) |
{ |
const char *stripped; |
assert(name); |
assert(prefix); |
stripped = name; |
while(*prefix) { |
if(*stripped != *prefix) |
return name; |
++stripped; |
++prefix; |
} |
return stripped; |
} |
#endif |
static const char * |
util_dump_enum_continuous(unsigned value, |
unsigned num_names, |
const char **names) |
{ |
if (value >= num_names) |
return UTIL_DUMP_INVALID_NAME; |
return names[value]; |
} |
#define DEFINE_UTIL_DUMP_CONTINUOUS(_name) \ |
const char * \ |
util_dump_##_name(unsigned value, boolean shortened) \ |
{ \ |
if(shortened) \ |
return util_dump_enum_continuous(value, Elements(util_dump_##_name##_short_names), util_dump_##_name##_short_names); \ |
else \ |
return util_dump_enum_continuous(value, Elements(util_dump_##_name##_names), util_dump_##_name##_names); \ |
} |
/** |
* Same as DEFINE_UTIL_DUMP_CONTINUOUS but with static assertions to detect |
* failures to update lists. |
*/ |
#define DEFINE_UTIL_DUMP_CONTINUOUS_COUNT(_name, _count) \ |
const char * \ |
util_dump_##_name(unsigned value, boolean shortened) \ |
{ \ |
STATIC_ASSERT(Elements(util_dump_##_name##_names) == _count); \ |
STATIC_ASSERT(Elements(util_dump_##_name##_short_names) == _count); \ |
if(shortened) \ |
return util_dump_enum_continuous(value, Elements(util_dump_##_name##_short_names), util_dump_##_name##_short_names); \ |
else \ |
return util_dump_enum_continuous(value, Elements(util_dump_##_name##_names), util_dump_##_name##_names); \ |
} |
static const char * |
util_dump_blend_factor_names[] = { |
UTIL_DUMP_INVALID_NAME, /* 0x0 */ |
"PIPE_BLENDFACTOR_ONE", |
"PIPE_BLENDFACTOR_SRC_COLOR", |
"PIPE_BLENDFACTOR_SRC_ALPHA", |
"PIPE_BLENDFACTOR_DST_ALPHA", |
"PIPE_BLENDFACTOR_DST_COLOR", |
"PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE", |
"PIPE_BLENDFACTOR_CONST_COLOR", |
"PIPE_BLENDFACTOR_CONST_ALPHA", |
"PIPE_BLENDFACTOR_SRC1_COLOR", |
"PIPE_BLENDFACTOR_SRC1_ALPHA", |
UTIL_DUMP_INVALID_NAME, /* 0x0b */ |
UTIL_DUMP_INVALID_NAME, /* 0x0c */ |
UTIL_DUMP_INVALID_NAME, /* 0x0d */ |
UTIL_DUMP_INVALID_NAME, /* 0x0e */ |
UTIL_DUMP_INVALID_NAME, /* 0x0f */ |
UTIL_DUMP_INVALID_NAME, /* 0x10 */ |
"PIPE_BLENDFACTOR_ZERO", |
"PIPE_BLENDFACTOR_INV_SRC_COLOR", |
"PIPE_BLENDFACTOR_INV_SRC_ALPHA", |
"PIPE_BLENDFACTOR_INV_DST_ALPHA", |
"PIPE_BLENDFACTOR_INV_DST_COLOR", |
UTIL_DUMP_INVALID_NAME, /* 0x16 */ |
"PIPE_BLENDFACTOR_INV_CONST_COLOR", |
"PIPE_BLENDFACTOR_INV_CONST_ALPHA", |
"PIPE_BLENDFACTOR_INV_SRC1_COLOR", |
"PIPE_BLENDFACTOR_INV_SRC1_ALPHA" |
}; |
static const char * |
util_dump_blend_factor_short_names[] = { |
UTIL_DUMP_INVALID_NAME, /* 0x0 */ |
"one", |
"src_color", |
"src_alpha", |
"dst_alpha", |
"dst_color", |
"src_alpha_saturate", |
"const_color", |
"const_alpha", |
"src1_color", |
"src1_alpha", |
UTIL_DUMP_INVALID_NAME, /* 0x0b */ |
UTIL_DUMP_INVALID_NAME, /* 0x0c */ |
UTIL_DUMP_INVALID_NAME, /* 0x0d */ |
UTIL_DUMP_INVALID_NAME, /* 0x0e */ |
UTIL_DUMP_INVALID_NAME, /* 0x0f */ |
UTIL_DUMP_INVALID_NAME, /* 0x10 */ |
"zero", |
"inv_src_color", |
"inv_src_alpha", |
"inv_dst_alpha", |
"inv_dst_color", |
UTIL_DUMP_INVALID_NAME, /* 0x16 */ |
"inv_const_color", |
"inv_const_alpha", |
"inv_src1_color", |
"inv_src1_alpha" |
}; |
DEFINE_UTIL_DUMP_CONTINUOUS(blend_factor) |
static const char * |
util_dump_blend_func_names[] = { |
"PIPE_BLEND_ADD", |
"PIPE_BLEND_SUBTRACT", |
"PIPE_BLEND_REVERSE_SUBTRACT", |
"PIPE_BLEND_MIN", |
"PIPE_BLEND_MAX" |
}; |
static const char * |
util_dump_blend_func_short_names[] = { |
"add", |
"sub", |
"rev_sub", |
"min", |
"max" |
}; |
DEFINE_UTIL_DUMP_CONTINUOUS(blend_func) |
static const char * |
util_dump_logicop_names[] = { |
"PIPE_LOGICOP_CLEAR", |
"PIPE_LOGICOP_NOR", |
"PIPE_LOGICOP_AND_INVERTED", |
"PIPE_LOGICOP_COPY_INVERTED", |
"PIPE_LOGICOP_AND_REVERSE", |
"PIPE_LOGICOP_INVERT", |
"PIPE_LOGICOP_XOR", |
"PIPE_LOGICOP_NAND", |
"PIPE_LOGICOP_AND", |
"PIPE_LOGICOP_EQUIV", |
"PIPE_LOGICOP_NOOP", |
"PIPE_LOGICOP_OR_INVERTED", |
"PIPE_LOGICOP_COPY", |
"PIPE_LOGICOP_OR_REVERSE", |
"PIPE_LOGICOP_OR", |
"PIPE_LOGICOP_SET" |
}; |
static const char * |
util_dump_logicop_short_names[] = { |
"clear", |
"nor", |
"and_inverted", |
"copy_inverted", |
"and_reverse", |
"invert", |
"xor", |
"nand", |
"and", |
"equiv", |
"noop", |
"or_inverted", |
"copy", |
"or_reverse", |
"or", |
"set" |
}; |
DEFINE_UTIL_DUMP_CONTINUOUS(logicop) |
static const char * |
util_dump_func_names[] = { |
"PIPE_FUNC_NEVER", |
"PIPE_FUNC_LESS", |
"PIPE_FUNC_EQUAL", |
"PIPE_FUNC_LEQUAL", |
"PIPE_FUNC_GREATER", |
"PIPE_FUNC_NOTEQUAL", |
"PIPE_FUNC_GEQUAL", |
"PIPE_FUNC_ALWAYS" |
}; |
static const char * |
util_dump_func_short_names[] = { |
"never", |
"less", |
"equal", |
"less_equal", |
"greater", |
"not_equal", |
"greater_equal", |
"always" |
}; |
DEFINE_UTIL_DUMP_CONTINUOUS(func) |
static const char * |
util_dump_stencil_op_names[] = { |
"PIPE_STENCIL_OP_KEEP", |
"PIPE_STENCIL_OP_ZERO", |
"PIPE_STENCIL_OP_REPLACE", |
"PIPE_STENCIL_OP_INCR", |
"PIPE_STENCIL_OP_DECR", |
"PIPE_STENCIL_OP_INCR_WRAP", |
"PIPE_STENCIL_OP_DECR_WRAP", |
"PIPE_STENCIL_OP_INVERT" |
}; |
static const char * |
util_dump_stencil_op_short_names[] = { |
"keep", |
"zero", |
"replace", |
"incr", |
"decr", |
"incr_wrap", |
"decr_wrap", |
"invert" |
}; |
DEFINE_UTIL_DUMP_CONTINUOUS(stencil_op) |
static const char * |
util_dump_tex_target_names[] = { |
"PIPE_BUFFER", |
"PIPE_TEXTURE_1D", |
"PIPE_TEXTURE_2D", |
"PIPE_TEXTURE_3D", |
"PIPE_TEXTURE_CUBE", |
"PIPE_TEXTURE_RECT", |
"PIPE_TEXTURE_1D_ARRAY", |
"PIPE_TEXTURE_2D_ARRAY", |
"PIPE_TEXTURE_CUBE_ARRAY", |
}; |
static const char * |
util_dump_tex_target_short_names[] = { |
"buffer", |
"1d", |
"2d", |
"3d", |
"cube", |
"rect", |
"1d_array", |
"2d_array", |
"cube_array", |
}; |
DEFINE_UTIL_DUMP_CONTINUOUS_COUNT(tex_target, PIPE_MAX_TEXTURE_TYPES) |
static const char * |
util_dump_tex_wrap_names[] = { |
"PIPE_TEX_WRAP_REPEAT", |
"PIPE_TEX_WRAP_CLAMP", |
"PIPE_TEX_WRAP_CLAMP_TO_EDGE", |
"PIPE_TEX_WRAP_CLAMP_TO_BORDER", |
"PIPE_TEX_WRAP_MIRROR_REPEAT", |
"PIPE_TEX_WRAP_MIRROR_CLAMP", |
"PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE", |
"PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER" |
}; |
static const char * |
util_dump_tex_wrap_short_names[] = { |
"repeat", |
"clamp", |
"clamp_to_edge", |
"clamp_to_border", |
"mirror_repeat", |
"mirror_clamp", |
"mirror_clamp_to_edge", |
"mirror_clamp_to_border" |
}; |
DEFINE_UTIL_DUMP_CONTINUOUS(tex_wrap) |
static const char * |
util_dump_tex_mipfilter_names[] = { |
"PIPE_TEX_MIPFILTER_NEAREST", |
"PIPE_TEX_MIPFILTER_LINEAR", |
"PIPE_TEX_MIPFILTER_NONE" |
}; |
static const char * |
util_dump_tex_mipfilter_short_names[] = { |
"nearest", |
"linear", |
"none" |
}; |
DEFINE_UTIL_DUMP_CONTINUOUS(tex_mipfilter) |
static const char * |
util_dump_tex_filter_names[] = { |
"PIPE_TEX_FILTER_NEAREST", |
"PIPE_TEX_FILTER_LINEAR" |
}; |
static const char * |
util_dump_tex_filter_short_names[] = { |
"nearest", |
"linear" |
}; |
DEFINE_UTIL_DUMP_CONTINUOUS(tex_filter) |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_dump_state.c |
---|
0,0 → 1,836 |
/************************************************************************** |
* |
* Copyright 2008-2010 VMware, Inc. |
* 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 VMWARE 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 "pipe/p_compiler.h" |
#include "util/u_memory.h" |
#include "util/u_string.h" |
#include "util/u_format.h" |
#include "tgsi/tgsi_dump.h" |
#include "u_dump.h" |
/* |
* Dump primitives |
*/ |
static INLINE void |
util_stream_writef(FILE *stream, const char *format, ...) |
{ |
static char buf[1024]; |
unsigned len; |
va_list ap; |
va_start(ap, format); |
len = util_vsnprintf(buf, sizeof(buf), format, ap); |
va_end(ap); |
fwrite(buf, len, 1, stream); |
} |
static void |
util_dump_bool(FILE *stream, int value) |
{ |
util_stream_writef(stream, "%c", value ? '1' : '0'); |
} |
static void |
util_dump_int(FILE *stream, long long int value) |
{ |
util_stream_writef(stream, "%lli", value); |
} |
static void |
util_dump_uint(FILE *stream, long long unsigned value) |
{ |
util_stream_writef(stream, "%llu", value); |
} |
static void |
util_dump_float(FILE *stream, double value) |
{ |
util_stream_writef(stream, "%g", value); |
} |
static void |
util_dump_string(FILE *stream, const char *str) |
{ |
fputs("\"", stream); |
fputs(str, stream); |
fputs("\"", stream); |
} |
static void |
util_dump_enum(FILE *stream, const char *value) |
{ |
fputs(value, stream); |
} |
static void |
util_dump_array_begin(FILE *stream) |
{ |
fputs("{", stream); |
} |
static void |
util_dump_array_end(FILE *stream) |
{ |
fputs("}", stream); |
} |
static void |
util_dump_elem_begin(FILE *stream) |
{ |
} |
static void |
util_dump_elem_end(FILE *stream) |
{ |
fputs(", ", stream); |
} |
static void |
util_dump_struct_begin(FILE *stream, const char *name) |
{ |
fputs("{", stream); |
} |
static void |
util_dump_struct_end(FILE *stream) |
{ |
fputs("}", stream); |
} |
static void |
util_dump_member_begin(FILE *stream, const char *name) |
{ |
util_stream_writef(stream, "%s = ", name); |
} |
static void |
util_dump_member_end(FILE *stream) |
{ |
fputs(", ", stream); |
} |
static void |
util_dump_null(FILE *stream) |
{ |
fputs("NULL", stream); |
} |
static void |
util_dump_ptr(FILE *stream, const void *value) |
{ |
if(value) |
util_stream_writef(stream, "0x%08lx", (unsigned long)(uintptr_t)value); |
else |
util_dump_null(stream); |
} |
/* |
* Code saving macros. |
*/ |
#define util_dump_arg(_stream, _type, _arg) \ |
do { \ |
util_dump_arg_begin(_stream, #_arg); \ |
util_dump_##_type(_stream, _arg); \ |
util_dump_arg_end(_stream); \ |
} while(0) |
#define util_dump_ret(_stream, _type, _arg) \ |
do { \ |
util_dump_ret_begin(_stream); \ |
util_dump_##_type(_stream, _arg); \ |
util_dump_ret_end(_stream); \ |
} while(0) |
#define util_dump_array(_stream, _type, _obj, _size) \ |
do { \ |
size_t idx; \ |
util_dump_array_begin(_stream); \ |
for(idx = 0; idx < (_size); ++idx) { \ |
util_dump_elem_begin(_stream); \ |
util_dump_##_type(_stream, (_obj)[idx]); \ |
util_dump_elem_end(_stream); \ |
} \ |
util_dump_array_end(_stream); \ |
} while(0) |
#define util_dump_struct_array(_stream, _type, _obj, _size) \ |
do { \ |
size_t idx; \ |
util_dump_array_begin(_stream); \ |
for(idx = 0; idx < (_size); ++idx) { \ |
util_dump_elem_begin(_stream); \ |
util_dump_##_type(_stream, &(_obj)[idx]); \ |
util_dump_elem_end(_stream); \ |
} \ |
util_dump_array_end(_stream); \ |
} while(0) |
#define util_dump_member(_stream, _type, _obj, _member) \ |
do { \ |
util_dump_member_begin(_stream, #_member); \ |
util_dump_##_type(_stream, (_obj)->_member); \ |
util_dump_member_end(_stream); \ |
} while(0) |
#define util_dump_arg_array(_stream, _type, _arg, _size) \ |
do { \ |
util_dump_arg_begin(_stream, #_arg); \ |
util_dump_array(_stream, _type, _arg, _size); \ |
util_dump_arg_end(_stream); \ |
} while(0) |
#define util_dump_member_array(_stream, _type, _obj, _member) \ |
do { \ |
util_dump_member_begin(_stream, #_member); \ |
util_dump_array(_stream, _type, (_obj)->_member, sizeof((_obj)->_member)/sizeof((_obj)->_member[0])); \ |
util_dump_member_end(_stream); \ |
} while(0) |
/* |
* Wrappers for enum -> string dumpers. |
*/ |
static void |
util_dump_format(FILE *stream, enum pipe_format format) |
{ |
util_dump_enum(stream, util_format_name(format)); |
} |
static void |
util_dump_enum_blend_factor(FILE *stream, unsigned value) |
{ |
util_dump_enum(stream, util_dump_blend_factor(value, TRUE)); |
} |
static void |
util_dump_enum_blend_func(FILE *stream, unsigned value) |
{ |
util_dump_enum(stream, util_dump_blend_func(value, TRUE)); |
} |
static void |
util_dump_enum_func(FILE *stream, unsigned value) |
{ |
util_dump_enum(stream, util_dump_func(value, TRUE)); |
} |
/* |
* Public functions |
*/ |
void |
util_dump_template(FILE *stream, const struct pipe_resource *templat) |
{ |
if(!templat) { |
util_dump_null(stream); |
return; |
} |
util_dump_struct_begin(stream, "pipe_resource"); |
util_dump_member(stream, int, templat, target); |
util_dump_member(stream, format, templat, format); |
util_dump_member_begin(stream, "width"); |
util_dump_uint(stream, templat->width0); |
util_dump_member_end(stream); |
util_dump_member_begin(stream, "height"); |
util_dump_uint(stream, templat->height0); |
util_dump_member_end(stream); |
util_dump_member_begin(stream, "depth"); |
util_dump_uint(stream, templat->depth0); |
util_dump_member_end(stream); |
util_dump_member_begin(stream, "array_size"); |
util_dump_uint(stream, templat->array_size); |
util_dump_member_end(stream); |
util_dump_member(stream, uint, templat, last_level); |
util_dump_member(stream, uint, templat, usage); |
util_dump_member(stream, uint, templat, bind); |
util_dump_member(stream, uint, templat, flags); |
util_dump_struct_end(stream); |
} |
void |
util_dump_rasterizer_state(FILE *stream, const struct pipe_rasterizer_state *state) |
{ |
if(!state) { |
util_dump_null(stream); |
return; |
} |
util_dump_struct_begin(stream, "pipe_rasterizer_state"); |
util_dump_member(stream, bool, state, flatshade); |
util_dump_member(stream, bool, state, light_twoside); |
util_dump_member(stream, bool, state, clamp_vertex_color); |
util_dump_member(stream, bool, state, clamp_fragment_color); |
util_dump_member(stream, uint, state, front_ccw); |
util_dump_member(stream, uint, state, cull_face); |
util_dump_member(stream, uint, state, fill_front); |
util_dump_member(stream, uint, state, fill_back); |
util_dump_member(stream, bool, state, offset_point); |
util_dump_member(stream, bool, state, offset_line); |
util_dump_member(stream, bool, state, offset_tri); |
util_dump_member(stream, bool, state, scissor); |
util_dump_member(stream, bool, state, poly_smooth); |
util_dump_member(stream, bool, state, poly_stipple_enable); |
util_dump_member(stream, bool, state, point_smooth); |
util_dump_member(stream, uint, state, sprite_coord_enable); |
util_dump_member(stream, bool, state, sprite_coord_mode); |
util_dump_member(stream, bool, state, point_quad_rasterization); |
util_dump_member(stream, bool, state, point_size_per_vertex); |
util_dump_member(stream, bool, state, multisample); |
util_dump_member(stream, bool, state, line_smooth); |
util_dump_member(stream, bool, state, line_stipple_enable); |
util_dump_member(stream, uint, state, line_stipple_factor); |
util_dump_member(stream, uint, state, line_stipple_pattern); |
util_dump_member(stream, bool, state, line_last_pixel); |
util_dump_member(stream, bool, state, flatshade_first); |
util_dump_member(stream, bool, state, half_pixel_center); |
util_dump_member(stream, bool, state, bottom_edge_rule); |
util_dump_member(stream, bool, state, rasterizer_discard); |
util_dump_member(stream, bool, state, depth_clip); |
util_dump_member(stream, uint, state, clip_plane_enable); |
util_dump_member(stream, float, state, line_width); |
util_dump_member(stream, float, state, point_size); |
util_dump_member(stream, float, state, offset_units); |
util_dump_member(stream, float, state, offset_scale); |
util_dump_member(stream, float, state, offset_clamp); |
util_dump_struct_end(stream); |
} |
void |
util_dump_poly_stipple(FILE *stream, const struct pipe_poly_stipple *state) |
{ |
if(!state) { |
util_dump_null(stream); |
return; |
} |
util_dump_struct_begin(stream, "pipe_poly_stipple"); |
util_dump_member_begin(stream, "stipple"); |
util_dump_member_array(stream, uint, state, stipple); |
util_dump_member_end(stream); |
util_dump_struct_end(stream); |
} |
void |
util_dump_viewport_state(FILE *stream, const struct pipe_viewport_state *state) |
{ |
if(!state) { |
util_dump_null(stream); |
return; |
} |
util_dump_struct_begin(stream, "pipe_viewport_state"); |
util_dump_member_array(stream, float, state, scale); |
util_dump_member_array(stream, float, state, translate); |
util_dump_struct_end(stream); |
} |
void |
util_dump_scissor_state(FILE *stream, const struct pipe_scissor_state *state) |
{ |
if(!state) { |
util_dump_null(stream); |
return; |
} |
util_dump_struct_begin(stream, "pipe_scissor_state"); |
util_dump_member(stream, uint, state, minx); |
util_dump_member(stream, uint, state, miny); |
util_dump_member(stream, uint, state, maxx); |
util_dump_member(stream, uint, state, maxy); |
util_dump_struct_end(stream); |
} |
void |
util_dump_clip_state(FILE *stream, const struct pipe_clip_state *state) |
{ |
unsigned i; |
if(!state) { |
util_dump_null(stream); |
return; |
} |
util_dump_struct_begin(stream, "pipe_clip_state"); |
util_dump_member_begin(stream, "ucp"); |
util_dump_array_begin(stream); |
for(i = 0; i < PIPE_MAX_CLIP_PLANES; ++i) { |
util_dump_elem_begin(stream); |
util_dump_array(stream, float, state->ucp[i], 4); |
util_dump_elem_end(stream); |
} |
util_dump_array_end(stream); |
util_dump_member_end(stream); |
util_dump_struct_end(stream); |
} |
void |
util_dump_shader_state(FILE *stream, const struct pipe_shader_state *state) |
{ |
char str[8192]; |
unsigned i; |
if(!state) { |
util_dump_null(stream); |
return; |
} |
tgsi_dump_str(state->tokens, 0, str, sizeof(str)); |
util_dump_struct_begin(stream, "pipe_shader_state"); |
util_dump_member_begin(stream, "tokens"); |
util_dump_string(stream, str); |
util_dump_member_end(stream); |
util_dump_member_begin(stream, "stream_output"); |
util_dump_struct_begin(stream, "pipe_stream_output_info"); |
util_dump_member(stream, uint, &state->stream_output, num_outputs); |
util_dump_array(stream, uint, state->stream_output.stride, |
Elements(state->stream_output.stride)); |
util_dump_array_begin(stream); |
for(i = 0; i < state->stream_output.num_outputs; ++i) { |
util_dump_elem_begin(stream); |
util_dump_struct_begin(stream, ""); /* anonymous */ |
util_dump_member(stream, uint, &state->stream_output.output[i], register_index); |
util_dump_member(stream, uint, &state->stream_output.output[i], start_component); |
util_dump_member(stream, uint, &state->stream_output.output[i], num_components); |
util_dump_member(stream, uint, &state->stream_output.output[i], output_buffer); |
util_dump_struct_end(stream); |
util_dump_elem_end(stream); |
} |
util_dump_array_end(stream); |
util_dump_struct_end(stream); |
util_dump_member_end(stream); |
util_dump_struct_end(stream); |
} |
void |
util_dump_depth_stencil_alpha_state(FILE *stream, const struct pipe_depth_stencil_alpha_state *state) |
{ |
unsigned i; |
if(!state) { |
util_dump_null(stream); |
return; |
} |
util_dump_struct_begin(stream, "pipe_depth_stencil_alpha_state"); |
util_dump_member_begin(stream, "depth"); |
util_dump_struct_begin(stream, "pipe_depth_state"); |
util_dump_member(stream, bool, &state->depth, enabled); |
if (state->depth.enabled) { |
util_dump_member(stream, bool, &state->depth, writemask); |
util_dump_member(stream, enum_func, &state->depth, func); |
} |
util_dump_struct_end(stream); |
util_dump_member_end(stream); |
util_dump_member_begin(stream, "stencil"); |
util_dump_array_begin(stream); |
for(i = 0; i < Elements(state->stencil); ++i) { |
util_dump_elem_begin(stream); |
util_dump_struct_begin(stream, "pipe_stencil_state"); |
util_dump_member(stream, bool, &state->stencil[i], enabled); |
if (state->stencil[i].enabled) { |
util_dump_member(stream, enum_func, &state->stencil[i], func); |
util_dump_member(stream, uint, &state->stencil[i], fail_op); |
util_dump_member(stream, uint, &state->stencil[i], zpass_op); |
util_dump_member(stream, uint, &state->stencil[i], zfail_op); |
util_dump_member(stream, uint, &state->stencil[i], valuemask); |
util_dump_member(stream, uint, &state->stencil[i], writemask); |
} |
util_dump_struct_end(stream); |
util_dump_elem_end(stream); |
} |
util_dump_array_end(stream); |
util_dump_member_end(stream); |
util_dump_member_begin(stream, "alpha"); |
util_dump_struct_begin(stream, "pipe_alpha_state"); |
util_dump_member(stream, bool, &state->alpha, enabled); |
if (state->alpha.enabled) { |
util_dump_member(stream, enum_func, &state->alpha, func); |
util_dump_member(stream, float, &state->alpha, ref_value); |
} |
util_dump_struct_end(stream); |
util_dump_member_end(stream); |
util_dump_struct_end(stream); |
} |
void |
util_dump_rt_blend_state(FILE *stream, const struct pipe_rt_blend_state *state) |
{ |
util_dump_struct_begin(stream, "pipe_rt_blend_state"); |
util_dump_member(stream, uint, state, blend_enable); |
if (state->blend_enable) { |
util_dump_member(stream, enum_blend_func, state, rgb_func); |
util_dump_member(stream, enum_blend_factor, state, rgb_src_factor); |
util_dump_member(stream, enum_blend_factor, state, rgb_dst_factor); |
util_dump_member(stream, enum_blend_func, state, alpha_func); |
util_dump_member(stream, enum_blend_factor, state, alpha_src_factor); |
util_dump_member(stream, enum_blend_factor, state, alpha_dst_factor); |
} |
util_dump_member(stream, uint, state, colormask); |
util_dump_struct_end(stream); |
} |
void |
util_dump_blend_state(FILE *stream, const struct pipe_blend_state *state) |
{ |
unsigned valid_entries = 1; |
if(!state) { |
util_dump_null(stream); |
return; |
} |
util_dump_struct_begin(stream, "pipe_blend_state"); |
util_dump_member(stream, bool, state, dither); |
util_dump_member(stream, bool, state, logicop_enable); |
if (state->logicop_enable) { |
util_dump_member(stream, enum_func, state, logicop_func); |
} |
else { |
util_dump_member(stream, bool, state, independent_blend_enable); |
util_dump_member_begin(stream, "rt"); |
if (state->independent_blend_enable) |
valid_entries = PIPE_MAX_COLOR_BUFS; |
util_dump_struct_array(stream, rt_blend_state, state->rt, valid_entries); |
util_dump_member_end(stream); |
} |
util_dump_struct_end(stream); |
} |
void |
util_dump_blend_color(FILE *stream, const struct pipe_blend_color *state) |
{ |
if(!state) { |
util_dump_null(stream); |
return; |
} |
util_dump_struct_begin(stream, "pipe_blend_color"); |
util_dump_member_array(stream, float, state, color); |
util_dump_struct_end(stream); |
} |
void |
util_dump_stencil_ref(FILE *stream, const struct pipe_stencil_ref *state) |
{ |
if(!state) { |
util_dump_null(stream); |
return; |
} |
util_dump_struct_begin(stream, "pipe_stencil_ref"); |
util_dump_member_array(stream, uint, state, ref_value); |
util_dump_struct_end(stream); |
} |
void |
util_dump_framebuffer_state(FILE *stream, const struct pipe_framebuffer_state *state) |
{ |
util_dump_struct_begin(stream, "pipe_framebuffer_state"); |
util_dump_member(stream, uint, state, width); |
util_dump_member(stream, uint, state, height); |
util_dump_member(stream, uint, state, nr_cbufs); |
util_dump_member_array(stream, ptr, state, cbufs); |
util_dump_member(stream, ptr, state, zsbuf); |
util_dump_struct_end(stream); |
} |
void |
util_dump_sampler_state(FILE *stream, const struct pipe_sampler_state *state) |
{ |
if(!state) { |
util_dump_null(stream); |
return; |
} |
util_dump_struct_begin(stream, "pipe_sampler_state"); |
util_dump_member(stream, uint, state, wrap_s); |
util_dump_member(stream, uint, state, wrap_t); |
util_dump_member(stream, uint, state, wrap_r); |
util_dump_member(stream, uint, state, min_img_filter); |
util_dump_member(stream, uint, state, min_mip_filter); |
util_dump_member(stream, uint, state, mag_img_filter); |
util_dump_member(stream, uint, state, compare_mode); |
util_dump_member(stream, enum_func, state, compare_func); |
util_dump_member(stream, bool, state, normalized_coords); |
util_dump_member(stream, uint, state, max_anisotropy); |
util_dump_member(stream, float, state, lod_bias); |
util_dump_member(stream, float, state, min_lod); |
util_dump_member(stream, float, state, max_lod); |
util_dump_member_array(stream, float, state, border_color.f); |
util_dump_struct_end(stream); |
} |
void |
util_dump_surface(FILE *stream, const struct pipe_surface *state) |
{ |
if(!state) { |
util_dump_null(stream); |
return; |
} |
util_dump_struct_begin(stream, "pipe_surface"); |
util_dump_member(stream, format, state, format); |
util_dump_member(stream, uint, state, width); |
util_dump_member(stream, uint, state, height); |
util_dump_member(stream, ptr, state, texture); |
util_dump_member(stream, uint, state, u.tex.level); |
util_dump_member(stream, uint, state, u.tex.first_layer); |
util_dump_member(stream, uint, state, u.tex.last_layer); |
util_dump_struct_end(stream); |
} |
void |
util_dump_transfer(FILE *stream, const struct pipe_transfer *state) |
{ |
if(!state) { |
util_dump_null(stream); |
return; |
} |
util_dump_struct_begin(stream, "pipe_transfer"); |
util_dump_member(stream, ptr, state, resource); |
util_dump_member(stream, uint, state, level); |
util_dump_member(stream, uint, state, usage); |
util_dump_member_begin(stream, "box"); |
util_dump_box(stream, &state->box); |
util_dump_member_end(stream); |
util_dump_member(stream, uint, state, stride); |
util_dump_member(stream, uint, state, layer_stride); |
util_dump_struct_end(stream); |
} |
void |
util_dump_vertex_buffer(FILE *stream, const struct pipe_vertex_buffer *state) |
{ |
if(!state) { |
util_dump_null(stream); |
return; |
} |
util_dump_struct_begin(stream, "pipe_vertex_buffer"); |
util_dump_member(stream, uint, state, stride); |
util_dump_member(stream, uint, state, buffer_offset); |
util_dump_member(stream, ptr, state, buffer); |
util_dump_struct_end(stream); |
} |
void |
util_dump_vertex_element(FILE *stream, const struct pipe_vertex_element *state) |
{ |
if(!state) { |
util_dump_null(stream); |
return; |
} |
util_dump_struct_begin(stream, "pipe_vertex_element"); |
util_dump_member(stream, uint, state, src_offset); |
util_dump_member(stream, uint, state, instance_divisor); |
util_dump_member(stream, uint, state, vertex_buffer_index); |
util_dump_member(stream, format, state, src_format); |
util_dump_struct_end(stream); |
} |
void |
util_dump_draw_info(FILE *stream, const struct pipe_draw_info *state) |
{ |
if(!state) { |
util_dump_null(stream); |
return; |
} |
util_dump_struct_begin(stream, "pipe_draw_info"); |
util_dump_member(stream, bool, state, indexed); |
util_dump_member(stream, uint, state, mode); |
util_dump_member(stream, uint, state, start); |
util_dump_member(stream, uint, state, count); |
util_dump_member(stream, uint, state, start_instance); |
util_dump_member(stream, uint, state, instance_count); |
util_dump_member(stream, int, state, index_bias); |
util_dump_member(stream, uint, state, min_index); |
util_dump_member(stream, uint, state, max_index); |
util_dump_member(stream, bool, state, primitive_restart); |
util_dump_member(stream, uint, state, restart_index); |
util_dump_member(stream, ptr, state, count_from_stream_output); |
util_dump_struct_end(stream); |
} |
void util_dump_box(FILE *stream, const struct pipe_box *box) |
{ |
if(!box) { |
util_dump_null(stream); |
return; |
} |
util_dump_struct_begin(stream, "pipe_box"); |
util_dump_member(stream, int, box, x); |
util_dump_member(stream, int, box, y); |
util_dump_member(stream, int, box, z); |
util_dump_member(stream, int, box, width); |
util_dump_member(stream, int, box, height); |
util_dump_member(stream, int, box, depth); |
util_dump_struct_end(stream); |
} |
void util_dump_blit_info(FILE *stream, const struct pipe_blit_info *info) |
{ |
char mask[7]; |
if (!info) { |
util_dump_null(stream); |
return; |
} |
util_dump_struct_begin(stream, "pipe_blit_info"); |
util_dump_member_begin(stream, "dst"); |
util_dump_struct_begin(stream, "dst"); |
util_dump_member(stream, ptr, &info->dst, resource); |
util_dump_member(stream, uint, &info->dst, level); |
util_dump_member(stream, format, &info->dst, format); |
util_dump_member_begin(stream, "box"); |
util_dump_box(stream, &info->dst.box); |
util_dump_member_end(stream); |
util_dump_struct_end(stream); |
util_dump_member_end(stream); |
util_dump_member_begin(stream, "src"); |
util_dump_struct_begin(stream, "src"); |
util_dump_member(stream, ptr, &info->src, resource); |
util_dump_member(stream, uint, &info->src, level); |
util_dump_member(stream, format, &info->src, format); |
util_dump_member_begin(stream, "box"); |
util_dump_box(stream, &info->src.box); |
util_dump_member_end(stream); |
util_dump_struct_end(stream); |
util_dump_member_end(stream); |
mask[0] = (info->mask & PIPE_MASK_R) ? 'R' : '-'; |
mask[1] = (info->mask & PIPE_MASK_G) ? 'G' : '-'; |
mask[2] = (info->mask & PIPE_MASK_B) ? 'B' : '-'; |
mask[3] = (info->mask & PIPE_MASK_A) ? 'A' : '-'; |
mask[4] = (info->mask & PIPE_MASK_Z) ? 'Z' : '-'; |
mask[5] = (info->mask & PIPE_MASK_S) ? 'S' : '-'; |
mask[6] = 0; |
util_dump_member_begin(stream, "mask"); |
util_dump_string(stream, mask); |
util_dump_member_end(stream); |
util_dump_member(stream, uint, info, filter); |
util_dump_member(stream, bool, info, scissor_enable); |
util_dump_member_begin(stream, "scissor"); |
util_dump_scissor_state(stream, &info->scissor); |
util_dump_member_end(stream); |
util_dump_struct_end(stream); |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_dynarray.h |
---|
0,0 → 1,114 |
/************************************************************************** |
* |
* Copyright 2010 Luca Barbieri |
* |
* 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, sublicense, 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 NONINFRINGEMENT. |
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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_DYNARRAY_H |
#define U_DYNARRAY_H |
#include "pipe/p_compiler.h" |
#include "util/u_memory.h" |
/* A zero-initialized version of this is guaranteed to represent an |
* empty array. |
* |
* Also, size <= capacity and data != 0 if and only if capacity != 0 |
* capacity will always be the allocation size of data |
*/ |
struct util_dynarray |
{ |
void *data; |
unsigned size; |
unsigned capacity; |
}; |
static INLINE void |
util_dynarray_init(struct util_dynarray *buf) |
{ |
memset(buf, 0, sizeof(*buf)); |
} |
static INLINE void |
util_dynarray_fini(struct util_dynarray *buf) |
{ |
if(buf->data) |
{ |
FREE(buf->data); |
util_dynarray_init(buf); |
} |
} |
/* use util_dynarray_trim to reduce the allocated storage */ |
static INLINE void * |
util_dynarray_resize(struct util_dynarray *buf, unsigned newsize) |
{ |
char *p; |
if(newsize > buf->capacity) |
{ |
unsigned newcap = buf->capacity << 1; |
if(newsize > newcap) |
newcap = newsize; |
buf->data = REALLOC(buf->data, buf->capacity, newcap); |
buf->capacity = newcap; |
} |
p = (char *)buf->data + buf->size; |
buf->size = newsize; |
return p; |
} |
static INLINE void * |
util_dynarray_grow(struct util_dynarray *buf, int diff) |
{ |
return util_dynarray_resize(buf, buf->size + diff); |
} |
static INLINE void |
util_dynarray_trim(struct util_dynarray *buf) |
{ |
if (buf->size != buf->capacity) { |
if (buf->size) { |
buf->data = REALLOC(buf->data, buf->capacity, buf->size); |
buf->capacity = buf->size; |
} |
else { |
FREE(buf->data); |
buf->data = 0; |
buf->capacity = 0; |
} |
} |
} |
#define util_dynarray_append(buf, type, v) do {type __v = (v); memcpy(util_dynarray_grow((buf), sizeof(type)), &__v, sizeof(type));} while(0) |
#define util_dynarray_top_ptr(buf, type) (type*)((char*)(buf)->data + (buf)->size - sizeof(type)) |
#define util_dynarray_top(buf, type) *util_dynarray_top_ptr(buf, type) |
#define util_dynarray_pop_ptr(buf, type) (type*)((char*)(buf)->data + ((buf)->size -= sizeof(type))) |
#define util_dynarray_pop(buf, type) *util_dynarray_pop_ptr(buf, type) |
#define util_dynarray_contains(buf, type) ((buf)->size >= sizeof(type)) |
#define util_dynarray_element(buf, type, idx) ((type*)(buf)->data + (idx)) |
#define util_dynarray_begin(buf) ((buf)->data) |
#define util_dynarray_end(buf) ((void*)util_dynarray_element((buf), char, (buf)->size)) |
#endif /* U_DYNARRAY_H */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_fifo.h |
---|
0,0 → 1,94 |
/************************************************************************** |
* |
* Copyright © 2009 Jakob Bornecrantz |
* |
* 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, sublicense, |
* 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 NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS 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_FIFO_H |
#define U_FIFO_H |
#include "util/u_memory.h" |
struct util_fifo |
{ |
size_t head; |
size_t tail; |
size_t num; |
size_t size; |
}; |
static INLINE struct util_fifo * |
u_fifo_create(size_t size) |
{ |
struct util_fifo *fifo; |
fifo = MALLOC(sizeof(*fifo) + size * sizeof(void*)); |
fifo->head = 0; |
fifo->tail = 0; |
fifo->num = 0; |
fifo->size = size; |
return fifo; |
} |
static INLINE boolean |
u_fifo_add(struct util_fifo *fifo, void *ptr) |
{ |
void **array = (void**)&fifo[1]; |
if (fifo->num >= fifo->size) |
return FALSE; |
if (++fifo->head >= fifo->size) |
fifo->head = 0; |
array[fifo->head] = ptr; |
++fifo->num; |
return TRUE; |
} |
static INLINE boolean |
u_fifo_pop(struct util_fifo *fifo, void **ptr) |
{ |
void **array = (void**)&fifo[1]; |
if (!fifo->num) |
return FALSE; |
if (++fifo->tail >= fifo->size) |
fifo->tail = 0; |
*ptr = array[fifo->tail]; |
++fifo->num; |
return TRUE; |
} |
static INLINE void |
u_fifo_destroy(struct util_fifo *fifo) |
{ |
FREE(fifo); |
} |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_format.c |
---|
0,0 → 1,725 |
/************************************************************************** |
* |
* Copyright 2010 VMware, Inc. |
* 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 VMWARE 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. |
* |
**************************************************************************/ |
/** |
* @file |
* Pixel format accessor functions. |
* |
* @author Jose Fonseca <jfonseca@vmware.com> |
*/ |
#include "u_math.h" |
#include "u_memory.h" |
#include "u_rect.h" |
#include "u_format.h" |
#include "u_format_s3tc.h" |
#include "pipe/p_defines.h" |
boolean |
util_format_is_float(enum pipe_format format) |
{ |
const struct util_format_description *desc = util_format_description(format); |
unsigned i; |
assert(desc); |
if (!desc) { |
return FALSE; |
} |
i = util_format_get_first_non_void_channel(format); |
if (i == -1) { |
return FALSE; |
} |
return desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT ? TRUE : FALSE; |
} |
/** Test if the format contains RGB, but not alpha */ |
boolean |
util_format_has_alpha(enum pipe_format format) |
{ |
const struct util_format_description *desc = |
util_format_description(format); |
return (desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB || |
desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) && |
desc->swizzle[3] != UTIL_FORMAT_SWIZZLE_1; |
} |
boolean |
util_format_is_luminance(enum pipe_format format) |
{ |
const struct util_format_description *desc = |
util_format_description(format); |
if ((desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB || |
desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) && |
desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_X && |
desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_X && |
desc->swizzle[2] == UTIL_FORMAT_SWIZZLE_X && |
desc->swizzle[3] == UTIL_FORMAT_SWIZZLE_1) { |
return TRUE; |
} |
return FALSE; |
} |
boolean |
util_format_is_pure_integer(enum pipe_format format) |
{ |
const struct util_format_description *desc = util_format_description(format); |
int i; |
/* Find the first non-void channel. */ |
i = util_format_get_first_non_void_channel(format); |
if (i == -1) |
return FALSE; |
return desc->channel[i].pure_integer ? TRUE : FALSE; |
} |
boolean |
util_format_is_pure_sint(enum pipe_format format) |
{ |
const struct util_format_description *desc = util_format_description(format); |
int i; |
i = util_format_get_first_non_void_channel(format); |
if (i == -1) |
return FALSE; |
return (desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED && desc->channel[i].pure_integer) ? TRUE : FALSE; |
} |
boolean |
util_format_is_pure_uint(enum pipe_format format) |
{ |
const struct util_format_description *desc = util_format_description(format); |
int i; |
i = util_format_get_first_non_void_channel(format); |
if (i == -1) |
return FALSE; |
return (desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED && desc->channel[i].pure_integer) ? TRUE : FALSE; |
} |
/** |
* Returns true if all non-void channels are normalized signed. |
*/ |
boolean |
util_format_is_snorm(enum pipe_format format) |
{ |
const struct util_format_description *desc = util_format_description(format); |
int i; |
if (desc->is_mixed) |
return FALSE; |
i = util_format_get_first_non_void_channel(format); |
if (i == -1) |
return FALSE; |
return desc->channel[i].type == UTIL_FORMAT_TYPE_SIGNED && |
!desc->channel[i].pure_integer && |
desc->channel[i].normalized; |
} |
boolean |
util_format_is_luminance_alpha(enum pipe_format format) |
{ |
const struct util_format_description *desc = |
util_format_description(format); |
if ((desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB || |
desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) && |
desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_X && |
desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_X && |
desc->swizzle[2] == UTIL_FORMAT_SWIZZLE_X && |
desc->swizzle[3] == UTIL_FORMAT_SWIZZLE_Y) { |
return TRUE; |
} |
return FALSE; |
} |
boolean |
util_format_is_intensity(enum pipe_format format) |
{ |
const struct util_format_description *desc = |
util_format_description(format); |
if ((desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB || |
desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) && |
desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_X && |
desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_X && |
desc->swizzle[2] == UTIL_FORMAT_SWIZZLE_X && |
desc->swizzle[3] == UTIL_FORMAT_SWIZZLE_X) { |
return TRUE; |
} |
return FALSE; |
} |
boolean |
util_format_is_supported(enum pipe_format format, unsigned bind) |
{ |
if (util_format_is_s3tc(format) && !util_format_s3tc_enabled) { |
return FALSE; |
} |
#ifndef TEXTURE_FLOAT_ENABLED |
if ((bind & PIPE_BIND_RENDER_TARGET) && |
format != PIPE_FORMAT_R9G9B9E5_FLOAT && |
format != PIPE_FORMAT_R11G11B10_FLOAT && |
util_format_is_float(format)) { |
return FALSE; |
} |
#endif |
return TRUE; |
} |
void |
util_format_read_4f(enum pipe_format format, |
float *dst, unsigned dst_stride, |
const void *src, unsigned src_stride, |
unsigned x, unsigned y, unsigned w, unsigned h) |
{ |
const struct util_format_description *format_desc; |
const uint8_t *src_row; |
float *dst_row; |
format_desc = util_format_description(format); |
assert(x % format_desc->block.width == 0); |
assert(y % format_desc->block.height == 0); |
src_row = (const uint8_t *)src + y*src_stride + x*(format_desc->block.bits/8); |
dst_row = dst; |
format_desc->unpack_rgba_float(dst_row, dst_stride, src_row, src_stride, w, h); |
} |
void |
util_format_write_4f(enum pipe_format format, |
const float *src, unsigned src_stride, |
void *dst, unsigned dst_stride, |
unsigned x, unsigned y, unsigned w, unsigned h) |
{ |
const struct util_format_description *format_desc; |
uint8_t *dst_row; |
const float *src_row; |
format_desc = util_format_description(format); |
assert(x % format_desc->block.width == 0); |
assert(y % format_desc->block.height == 0); |
dst_row = (uint8_t *)dst + y*dst_stride + x*(format_desc->block.bits/8); |
src_row = src; |
format_desc->pack_rgba_float(dst_row, dst_stride, src_row, src_stride, w, h); |
} |
void |
util_format_read_4ub(enum pipe_format format, uint8_t *dst, unsigned dst_stride, const void *src, unsigned src_stride, unsigned x, unsigned y, unsigned w, unsigned h) |
{ |
const struct util_format_description *format_desc; |
const uint8_t *src_row; |
uint8_t *dst_row; |
format_desc = util_format_description(format); |
assert(x % format_desc->block.width == 0); |
assert(y % format_desc->block.height == 0); |
src_row = (const uint8_t *)src + y*src_stride + x*(format_desc->block.bits/8); |
dst_row = dst; |
format_desc->unpack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, w, h); |
} |
void |
util_format_write_4ub(enum pipe_format format, const uint8_t *src, unsigned src_stride, void *dst, unsigned dst_stride, unsigned x, unsigned y, unsigned w, unsigned h) |
{ |
const struct util_format_description *format_desc; |
uint8_t *dst_row; |
const uint8_t *src_row; |
format_desc = util_format_description(format); |
assert(x % format_desc->block.width == 0); |
assert(y % format_desc->block.height == 0); |
dst_row = (uint8_t *)dst + y*dst_stride + x*(format_desc->block.bits/8); |
src_row = src; |
format_desc->pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, w, h); |
} |
void |
util_format_read_4ui(enum pipe_format format, |
unsigned *dst, unsigned dst_stride, |
const void *src, unsigned src_stride, |
unsigned x, unsigned y, unsigned w, unsigned h) |
{ |
const struct util_format_description *format_desc; |
const uint8_t *src_row; |
uint32_t *dst_row; |
format_desc = util_format_description(format); |
assert(x % format_desc->block.width == 0); |
assert(y % format_desc->block.height == 0); |
src_row = (const uint8_t *)src + y*src_stride + x*(format_desc->block.bits/8); |
dst_row = dst; |
format_desc->unpack_rgba_uint(dst_row, dst_stride, src_row, src_stride, w, h); |
} |
void |
util_format_write_4ui(enum pipe_format format, |
const unsigned int *src, unsigned src_stride, |
void *dst, unsigned dst_stride, |
unsigned x, unsigned y, unsigned w, unsigned h) |
{ |
const struct util_format_description *format_desc; |
uint8_t *dst_row; |
const uint32_t *src_row; |
format_desc = util_format_description(format); |
assert(x % format_desc->block.width == 0); |
assert(y % format_desc->block.height == 0); |
dst_row = (uint8_t *)dst + y*dst_stride + x*(format_desc->block.bits/8); |
src_row = src; |
format_desc->pack_rgba_uint(dst_row, dst_stride, src_row, src_stride, w, h); |
} |
void |
util_format_read_4i(enum pipe_format format, |
int *dst, unsigned dst_stride, |
const void *src, unsigned src_stride, |
unsigned x, unsigned y, unsigned w, unsigned h) |
{ |
const struct util_format_description *format_desc; |
const uint8_t *src_row; |
int32_t *dst_row; |
format_desc = util_format_description(format); |
assert(x % format_desc->block.width == 0); |
assert(y % format_desc->block.height == 0); |
src_row = (const uint8_t *)src + y*src_stride + x*(format_desc->block.bits/8); |
dst_row = dst; |
format_desc->unpack_rgba_sint(dst_row, dst_stride, src_row, src_stride, w, h); |
} |
void |
util_format_write_4i(enum pipe_format format, |
const int *src, unsigned src_stride, |
void *dst, unsigned dst_stride, |
unsigned x, unsigned y, unsigned w, unsigned h) |
{ |
const struct util_format_description *format_desc; |
uint8_t *dst_row; |
const int32_t *src_row; |
format_desc = util_format_description(format); |
assert(x % format_desc->block.width == 0); |
assert(y % format_desc->block.height == 0); |
dst_row = (uint8_t *)dst + y*dst_stride + x*(format_desc->block.bits/8); |
src_row = src; |
format_desc->pack_rgba_sint(dst_row, dst_stride, src_row, src_stride, w, h); |
} |
boolean |
util_is_format_compatible(const struct util_format_description *src_desc, |
const struct util_format_description *dst_desc) |
{ |
unsigned chan; |
if (src_desc->format == dst_desc->format) { |
return TRUE; |
} |
if (src_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN || |
dst_desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) { |
return FALSE; |
} |
if (src_desc->block.bits != dst_desc->block.bits || |
src_desc->nr_channels != dst_desc->nr_channels || |
src_desc->colorspace != dst_desc->colorspace) { |
return FALSE; |
} |
for (chan = 0; chan < 4; ++chan) { |
if (src_desc->channel[chan].size != |
dst_desc->channel[chan].size) { |
return FALSE; |
} |
} |
for (chan = 0; chan < 4; ++chan) { |
enum util_format_swizzle swizzle = dst_desc->swizzle[chan]; |
if (swizzle < 4) { |
if (src_desc->swizzle[chan] != swizzle) { |
return FALSE; |
} |
if ((src_desc->channel[swizzle].type != |
dst_desc->channel[swizzle].type) || |
(src_desc->channel[swizzle].normalized != |
dst_desc->channel[swizzle].normalized)) { |
return FALSE; |
} |
} |
} |
return TRUE; |
} |
boolean |
util_format_fits_8unorm(const struct util_format_description *format_desc) |
{ |
unsigned chan; |
/* |
* After linearized sRGB values require more than 8bits. |
*/ |
if (format_desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) { |
return FALSE; |
} |
switch (format_desc->layout) { |
case UTIL_FORMAT_LAYOUT_S3TC: |
/* |
* These are straight forward. |
*/ |
return TRUE; |
case UTIL_FORMAT_LAYOUT_RGTC: |
if (format_desc->format == PIPE_FORMAT_RGTC1_SNORM || |
format_desc->format == PIPE_FORMAT_RGTC2_SNORM || |
format_desc->format == PIPE_FORMAT_LATC1_SNORM || |
format_desc->format == PIPE_FORMAT_LATC2_SNORM) |
return FALSE; |
return TRUE; |
case UTIL_FORMAT_LAYOUT_PLAIN: |
/* |
* For these we can find a generic rule. |
*/ |
for (chan = 0; chan < format_desc->nr_channels; ++chan) { |
switch (format_desc->channel[chan].type) { |
case UTIL_FORMAT_TYPE_VOID: |
break; |
case UTIL_FORMAT_TYPE_UNSIGNED: |
if (!format_desc->channel[chan].normalized || |
format_desc->channel[chan].size > 8) { |
return FALSE; |
} |
break; |
default: |
return FALSE; |
} |
} |
return TRUE; |
default: |
/* |
* Handle all others on a case by case basis. |
*/ |
switch (format_desc->format) { |
case PIPE_FORMAT_R1_UNORM: |
case PIPE_FORMAT_UYVY: |
case PIPE_FORMAT_YUYV: |
case PIPE_FORMAT_R8G8_B8G8_UNORM: |
case PIPE_FORMAT_G8R8_G8B8_UNORM: |
return TRUE; |
default: |
return FALSE; |
} |
} |
} |
void |
util_format_translate(enum pipe_format dst_format, |
void *dst, unsigned dst_stride, |
unsigned dst_x, unsigned dst_y, |
enum pipe_format src_format, |
const void *src, unsigned src_stride, |
unsigned src_x, unsigned src_y, |
unsigned width, unsigned height) |
{ |
const struct util_format_description *dst_format_desc; |
const struct util_format_description *src_format_desc; |
uint8_t *dst_row; |
const uint8_t *src_row; |
unsigned x_step, y_step; |
unsigned dst_step; |
unsigned src_step; |
dst_format_desc = util_format_description(dst_format); |
src_format_desc = util_format_description(src_format); |
if (util_is_format_compatible(src_format_desc, dst_format_desc)) { |
/* |
* Trivial case. |
*/ |
util_copy_rect(dst, dst_format, dst_stride, dst_x, dst_y, |
width, height, src, (int)src_stride, |
src_x, src_y); |
return; |
} |
assert(dst_x % dst_format_desc->block.width == 0); |
assert(dst_y % dst_format_desc->block.height == 0); |
assert(src_x % src_format_desc->block.width == 0); |
assert(src_y % src_format_desc->block.height == 0); |
dst_row = (uint8_t *)dst + dst_y*dst_stride + dst_x*(dst_format_desc->block.bits/8); |
src_row = (const uint8_t *)src + src_y*src_stride + src_x*(src_format_desc->block.bits/8); |
/* |
* This works because all pixel formats have pixel blocks with power of two |
* sizes. |
*/ |
y_step = MAX2(dst_format_desc->block.height, src_format_desc->block.height); |
x_step = MAX2(dst_format_desc->block.width, src_format_desc->block.width); |
assert(y_step % dst_format_desc->block.height == 0); |
assert(y_step % src_format_desc->block.height == 0); |
dst_step = y_step / dst_format_desc->block.height * dst_stride; |
src_step = y_step / src_format_desc->block.height * src_stride; |
/* |
* TODO: double formats will loose precision |
* TODO: Add a special case for formats that are mere swizzles of each other |
*/ |
if (src_format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS || |
dst_format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) { |
float *tmp_z = NULL; |
uint8_t *tmp_s = NULL; |
assert(x_step == 1); |
assert(y_step == 1); |
if (src_format_desc->unpack_z_float && |
dst_format_desc->pack_z_float) { |
tmp_z = MALLOC(width * sizeof *tmp_z); |
} |
if (src_format_desc->unpack_s_8uint && |
dst_format_desc->pack_s_8uint) { |
tmp_s = MALLOC(width * sizeof *tmp_s); |
} |
while (height--) { |
if (tmp_z) { |
src_format_desc->unpack_z_float(tmp_z, 0, src_row, src_stride, width, 1); |
dst_format_desc->pack_z_float(dst_row, dst_stride, tmp_z, 0, width, 1); |
} |
if (tmp_s) { |
src_format_desc->unpack_s_8uint(tmp_s, 0, src_row, src_stride, width, 1); |
dst_format_desc->pack_s_8uint(dst_row, dst_stride, tmp_s, 0, width, 1); |
} |
dst_row += dst_step; |
src_row += src_step; |
} |
FREE(tmp_s); |
FREE(tmp_z); |
return; |
} |
if (util_format_fits_8unorm(src_format_desc) || |
util_format_fits_8unorm(dst_format_desc)) { |
unsigned tmp_stride; |
uint8_t *tmp_row; |
tmp_stride = MAX2(width, x_step) * 4 * sizeof *tmp_row; |
tmp_row = MALLOC(y_step * tmp_stride); |
if (!tmp_row) |
return; |
while (height >= y_step) { |
src_format_desc->unpack_rgba_8unorm(tmp_row, tmp_stride, src_row, src_stride, width, y_step); |
dst_format_desc->pack_rgba_8unorm(dst_row, dst_stride, tmp_row, tmp_stride, width, y_step); |
dst_row += dst_step; |
src_row += src_step; |
height -= y_step; |
} |
if (height) { |
src_format_desc->unpack_rgba_8unorm(tmp_row, tmp_stride, src_row, src_stride, width, height); |
dst_format_desc->pack_rgba_8unorm(dst_row, dst_stride, tmp_row, tmp_stride, width, height); |
} |
FREE(tmp_row); |
} |
else { |
unsigned tmp_stride; |
float *tmp_row; |
tmp_stride = MAX2(width, x_step) * 4 * sizeof *tmp_row; |
tmp_row = MALLOC(y_step * tmp_stride); |
if (!tmp_row) |
return; |
while (height >= y_step) { |
src_format_desc->unpack_rgba_float(tmp_row, tmp_stride, src_row, src_stride, width, y_step); |
dst_format_desc->pack_rgba_float(dst_row, dst_stride, tmp_row, tmp_stride, width, y_step); |
dst_row += dst_step; |
src_row += src_step; |
height -= y_step; |
} |
if (height) { |
src_format_desc->unpack_rgba_float(tmp_row, tmp_stride, src_row, src_stride, width, height); |
dst_format_desc->pack_rgba_float(dst_row, dst_stride, tmp_row, tmp_stride, width, height); |
} |
FREE(tmp_row); |
} |
} |
void util_format_compose_swizzles(const unsigned char swz1[4], |
const unsigned char swz2[4], |
unsigned char dst[4]) |
{ |
unsigned i; |
for (i = 0; i < 4; i++) { |
dst[i] = swz2[i] <= UTIL_FORMAT_SWIZZLE_W ? |
swz1[swz2[i]] : swz2[i]; |
} |
} |
void util_format_apply_color_swizzle(union pipe_color_union *dst, |
const union pipe_color_union *src, |
const unsigned char swz[4], |
const boolean is_integer) |
{ |
unsigned c; |
if (is_integer) { |
for (c = 0; c < 4; ++c) { |
switch (swz[c]) { |
case PIPE_SWIZZLE_RED: dst->ui[c] = src->ui[0]; break; |
case PIPE_SWIZZLE_GREEN: dst->ui[c] = src->ui[1]; break; |
case PIPE_SWIZZLE_BLUE: dst->ui[c] = src->ui[2]; break; |
case PIPE_SWIZZLE_ALPHA: dst->ui[c] = src->ui[3]; break; |
default: |
dst->ui[c] = (swz[c] == PIPE_SWIZZLE_ONE) ? 1 : 0; |
break; |
} |
} |
} else { |
for (c = 0; c < 4; ++c) { |
switch (swz[c]) { |
case PIPE_SWIZZLE_RED: dst->f[c] = src->f[0]; break; |
case PIPE_SWIZZLE_GREEN: dst->f[c] = src->f[1]; break; |
case PIPE_SWIZZLE_BLUE: dst->f[c] = src->f[2]; break; |
case PIPE_SWIZZLE_ALPHA: dst->f[c] = src->f[3]; break; |
default: |
dst->f[c] = (swz[c] == PIPE_SWIZZLE_ONE) ? 1.0f : 0.0f; |
break; |
} |
} |
} |
} |
void util_format_swizzle_4f(float *dst, const float *src, |
const unsigned char swz[4]) |
{ |
unsigned i; |
for (i = 0; i < 4; i++) { |
if (swz[i] <= UTIL_FORMAT_SWIZZLE_W) |
dst[i] = src[swz[i]]; |
else if (swz[i] == UTIL_FORMAT_SWIZZLE_0) |
dst[i] = 0; |
else if (swz[i] == UTIL_FORMAT_SWIZZLE_1) |
dst[i] = 1; |
} |
} |
void util_format_unswizzle_4f(float *dst, const float *src, |
const unsigned char swz[4]) |
{ |
unsigned i; |
for (i = 0; i < 4; i++) { |
switch (swz[i]) { |
case UTIL_FORMAT_SWIZZLE_X: |
dst[0] = src[i]; |
break; |
case UTIL_FORMAT_SWIZZLE_Y: |
dst[1] = src[i]; |
break; |
case UTIL_FORMAT_SWIZZLE_Z: |
dst[2] = src[i]; |
break; |
case UTIL_FORMAT_SWIZZLE_W: |
dst[3] = src[i]; |
break; |
} |
} |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_format.csv |
---|
0,0 → 1,374 |
########################################################################### |
# |
# Copyright 2009-2010 VMware, Inc. |
# 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 THE 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. |
# |
########################################################################### |
# This CSV file has the input data for u_format.h's struct |
# util_format_description. |
# |
# Each format entry contains: |
# - name, per enum pipe_format |
# - layout, per enum util_format_layout, in shortened lower caps |
# - pixel block's width |
# - pixel block's height |
# - channel encoding (only meaningful for plain layout), containing for each |
# channel the following information: |
# - type, one of |
# - 'x': void |
# - 'u': unsigned |
# - 's': signed |
# - 'h': fixed |
# - 'f': FLOAT |
# - optionally followed by 'n' if it is normalized |
# - optionally followed by 'p' if it is pure |
# - number of bits |
# - channel swizzle |
# - color space: rgb, yub, sz |
# |
# See also: |
# - http://msdn.microsoft.com/en-us/library/bb172558.aspx (D3D9) |
# - http://msdn.microsoft.com/en-us/library/bb205073.aspx#mapping_texture_formats (D3D9 -> D3D10) |
# - http://msdn.microsoft.com/en-us/library/bb173059.aspx (D3D10) |
# |
# Note that GL doesn't really specify the layout of internal formats. See |
# OpenGL 2.1 specification, Table 3.16, on the "Correspondence of sized |
# internal formats to base in- ternal formats, and desired component |
# resolutions for each sized internal format." |
# None |
# Described as regular uint_8 bytes, i.e. PIPE_FORMAT_R8_USCALED |
PIPE_FORMAT_NONE , plain, 1, 1, u8 , , , , x001, rgb |
# Typical rendertarget formats |
PIPE_FORMAT_B8G8R8A8_UNORM , plain, 1, 1, un8 , un8 , un8 , un8 , zyxw, rgb |
PIPE_FORMAT_B8G8R8X8_UNORM , plain, 1, 1, un8 , un8 , un8 , x8 , zyx1, rgb |
PIPE_FORMAT_A8R8G8B8_UNORM , plain, 1, 1, un8 , un8 , un8 , un8 , yzwx, rgb |
PIPE_FORMAT_X8R8G8B8_UNORM , plain, 1, 1, x8 , un8 , un8 , un8 , yzw1, rgb |
PIPE_FORMAT_A8B8G8R8_UNORM , plain, 1, 1, un8 , un8 , un8 , un8 , wzyx, rgb |
PIPE_FORMAT_X8B8G8R8_UNORM , plain, 1, 1, x8 , un8 , un8 , un8 , wzy1, rgb |
# PIPE_FORMAT_R8G8B8A8_UNORM is below |
PIPE_FORMAT_R8G8B8X8_UNORM , plain, 1, 1, un8 , un8 , un8 , x8 , xyz1, rgb |
PIPE_FORMAT_B5G5R5X1_UNORM , plain, 1, 1, un5 , un5 , un5 , x1 , zyx1, rgb |
PIPE_FORMAT_B5G5R5A1_UNORM , plain, 1, 1, un5 , un5 , un5 , un1 , zyxw, rgb |
PIPE_FORMAT_B4G4R4A4_UNORM , plain, 1, 1, un4 , un4 , un4 , un4 , zyxw, rgb |
PIPE_FORMAT_B4G4R4X4_UNORM , plain, 1, 1, un4 , un4 , un4 , x4 , zyx1, rgb |
PIPE_FORMAT_B5G6R5_UNORM , plain, 1, 1, un5 , un6 , un5 , , zyx1, rgb |
PIPE_FORMAT_R10G10B10A2_UNORM , plain, 1, 1, un10, un10, un10, un2 , xyzw, rgb |
PIPE_FORMAT_B10G10R10A2_UNORM , plain, 1, 1, un10, un10, un10, un2 , zyxw, rgb |
PIPE_FORMAT_B2G3R3_UNORM , plain, 1, 1, un2 , un3 , un3 , , zyx1, rgb |
# Luminance/Intensity/Alpha formats |
PIPE_FORMAT_L8_UNORM , plain, 1, 1, un8 , , , , xxx1, rgb |
PIPE_FORMAT_A8_UNORM , plain, 1, 1, un8 , , , , 000x, rgb |
PIPE_FORMAT_I8_UNORM , plain, 1, 1, un8 , , , , xxxx, rgb |
PIPE_FORMAT_L4A4_UNORM , plain, 1, 1, un4 , un4 , , , xxxy, rgb |
PIPE_FORMAT_L8A8_UNORM , plain, 1, 1, un8 , un8 , , , xxxy, rgb |
PIPE_FORMAT_L16_UNORM , plain, 1, 1, un16, , , , xxx1, rgb |
PIPE_FORMAT_A16_UNORM , plain, 1, 1, un16, , , , 000x, rgb |
PIPE_FORMAT_I16_UNORM , plain, 1, 1, un16, , , , xxxx, rgb |
PIPE_FORMAT_L16A16_UNORM , plain, 1, 1, un16, un16, , , xxxy, rgb |
PIPE_FORMAT_A8_SNORM , plain, 1, 1, sn8 , , , , 000x, rgb |
PIPE_FORMAT_L8_SNORM , plain, 1, 1, sn8 , , , , xxx1, rgb |
PIPE_FORMAT_L8A8_SNORM , plain, 1, 1, sn8 , sn8 , , , xxxy, rgb |
PIPE_FORMAT_I8_SNORM , plain, 1, 1, sn8 , , , , xxxx, rgb |
PIPE_FORMAT_A16_SNORM , plain, 1, 1, sn16, , , , 000x, rgb |
PIPE_FORMAT_L16_SNORM , plain, 1, 1, sn16, , , , xxx1, rgb |
PIPE_FORMAT_L16A16_SNORM , plain, 1, 1, sn16, sn16, , , xxxy, rgb |
PIPE_FORMAT_I16_SNORM , plain, 1, 1, sn16, , , , xxxx, rgb |
PIPE_FORMAT_A16_FLOAT , plain, 1, 1, f16 , , , , 000x, rgb |
PIPE_FORMAT_L16_FLOAT , plain, 1, 1, f16 , , , , xxx1, rgb |
PIPE_FORMAT_L16A16_FLOAT , plain, 1, 1, f16 , f16 , , , xxxy, rgb |
PIPE_FORMAT_I16_FLOAT , plain, 1, 1, f16 , , , , xxxx, rgb |
PIPE_FORMAT_A32_FLOAT , plain, 1, 1, f32 , , , , 000x, rgb |
PIPE_FORMAT_L32_FLOAT , plain, 1, 1, f32 , , , , xxx1, rgb |
PIPE_FORMAT_L32A32_FLOAT , plain, 1, 1, f32 , f32 , , , xxxy, rgb |
PIPE_FORMAT_I32_FLOAT , plain, 1, 1, f32 , , , , xxxx, rgb |
# SRGB formats |
PIPE_FORMAT_L8_SRGB , plain, 1, 1, un8 , , , , xxx1, srgb |
PIPE_FORMAT_L8A8_SRGB , plain, 1, 1, un8 , un8 , , , xxxy, srgb |
PIPE_FORMAT_R8G8B8_SRGB , plain, 1, 1, un8 , un8 , un8 , , xyz1, srgb |
PIPE_FORMAT_R8G8B8A8_SRGB , plain, 1, 1, un8 , un8 , un8 , un8 , xyzw, srgb |
PIPE_FORMAT_A8B8G8R8_SRGB , plain, 1, 1, un8 , un8 , un8 , un8 , wzyx, srgb |
PIPE_FORMAT_X8B8G8R8_SRGB , plain, 1, 1, x8 , un8 , un8 , un8 , wzy1, srgb |
PIPE_FORMAT_B8G8R8A8_SRGB , plain, 1, 1, un8 , un8 , un8 , un8 , zyxw, srgb |
PIPE_FORMAT_B8G8R8X8_SRGB , plain, 1, 1, un8 , un8 , un8 , x8 , zyx1, srgb |
PIPE_FORMAT_A8R8G8B8_SRGB , plain, 1, 1, un8 , un8 , un8 , un8 , yzwx, srgb |
PIPE_FORMAT_X8R8G8B8_SRGB , plain, 1, 1, x8 , un8 , un8 , un8 , yzw1, srgb |
# Mixed-sign formats (typically used for bump map textures) |
PIPE_FORMAT_R8SG8SB8UX8U_NORM , plain, 1, 1, sn8 , sn8 , un8 , x8 , xyz1, rgb |
PIPE_FORMAT_R10SG10SB10SA2U_NORM , plain, 1, 1, sn10, sn10, sn10, un2 , xyzw, rgb |
PIPE_FORMAT_R5SG5SB6U_NORM , plain, 1, 1, sn5 , sn5 , un6 , , xyz1, rgb |
# Depth-stencil formats |
PIPE_FORMAT_S8_UINT , plain, 1, 1, up8 , , , , _x__, zs |
PIPE_FORMAT_Z16_UNORM , plain, 1, 1, un16, , , , x___, zs |
PIPE_FORMAT_Z32_UNORM , plain, 1, 1, un32, , , , x___, zs |
PIPE_FORMAT_Z32_FLOAT , plain, 1, 1, f32 , , , , x___, zs |
PIPE_FORMAT_Z24_UNORM_S8_UINT , plain, 1, 1, un24, up8 , , , xy__, zs |
PIPE_FORMAT_S8_UINT_Z24_UNORM , plain, 1, 1, up8 , un24, , , yx__, zs |
PIPE_FORMAT_X24S8_UINT , plain, 1, 1, x24 , up8 , , , _y__, zs |
PIPE_FORMAT_S8X24_UINT , plain, 1, 1, up8 , x24 , , , _x__, zs |
PIPE_FORMAT_Z24X8_UNORM , plain, 1, 1, un24, x8 , , , x___, zs |
PIPE_FORMAT_X8Z24_UNORM , plain, 1, 1, x8 , un24, , , y___, zs |
PIPE_FORMAT_Z32_FLOAT_S8X24_UINT , plain, 1, 1, f32 , up8 , x24, , xy__, zs |
PIPE_FORMAT_X32_S8X24_UINT , plain, 1, 1, x32 , up8 , x24, , _y__, zs |
# YUV formats |
# http://www.fourcc.org/yuv.php#UYVY |
PIPE_FORMAT_UYVY , subsampled, 2, 1, x32 , , , , xyz1, yuv |
# http://www.fourcc.org/yuv.php#YUYV (a.k.a http://www.fourcc.org/yuv.php#YUY2) |
PIPE_FORMAT_YUYV , subsampled, 2, 1, x32 , , , , xyz1, yuv |
# same subsampling but with rgb channels |
PIPE_FORMAT_R8G8_B8G8_UNORM , subsampled, 2, 1, x32 , , , , xyz1, rgb |
PIPE_FORMAT_G8R8_G8B8_UNORM , subsampled, 2, 1, x32 , , , , xyz1, rgb |
PIPE_FORMAT_G8R8_B8R8_UNORM , subsampled, 2, 1, x32 , , , , yxz1, rgb |
PIPE_FORMAT_R8G8_R8B8_UNORM , subsampled, 2, 1, x32 , , , , yxz1, rgb |
# some special formats not fitting anywhere else |
PIPE_FORMAT_R11G11B10_FLOAT , other, 1, 1, x32 , , , , xyz1, rgb |
PIPE_FORMAT_R9G9B9E5_FLOAT , other, 1, 1, x32 , , , , xyz1, rgb |
PIPE_FORMAT_R1_UNORM , other, 8, 1, x8 , , , , x001, rgb |
# A.k.a. D3DFMT_CxV8U8 |
PIPE_FORMAT_R8G8Bx_SNORM , other, 1, 1, sn8 , sn8 , , , xyz1, rgb |
# Compressed formats |
# - http://en.wikipedia.org/wiki/S3_Texture_Compression |
# - http://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt |
# - http://www.opengl.org/registry/specs/ARB/texture_compression_rgtc.txt |
# - http://www.opengl.org/registry/specs/EXT/texture_compression_latc.txt |
# - http://www.khronos.org/registry/gles/extensions/OES/OES_compressed_ETC1_RGB8_texture.txt |
# - http://msdn.microsoft.com/en-us/library/bb694531.aspx |
PIPE_FORMAT_DXT1_RGB , s3tc, 4, 4, x64 , , , , xyz1, rgb |
PIPE_FORMAT_DXT1_RGBA , s3tc, 4, 4, x64 , , , , xyzw, rgb |
PIPE_FORMAT_DXT3_RGBA , s3tc, 4, 4, x128, , , , xyzw, rgb |
PIPE_FORMAT_DXT5_RGBA , s3tc, 4, 4, x128, , , , xyzw, rgb |
PIPE_FORMAT_DXT1_SRGB , s3tc, 4, 4, x64 , , , , xyz1, srgb |
PIPE_FORMAT_DXT1_SRGBA , s3tc, 4, 4, x64 , , , , xyzw, srgb |
PIPE_FORMAT_DXT3_SRGBA , s3tc, 4, 4, x128, , , , xyzw, srgb |
PIPE_FORMAT_DXT5_SRGBA , s3tc, 4, 4, x128, , , , xyzw, srgb |
PIPE_FORMAT_RGTC1_UNORM , rgtc, 4, 4, x64, , , , x001, rgb |
PIPE_FORMAT_RGTC1_SNORM , rgtc, 4, 4, x64, , , , x001, rgb |
PIPE_FORMAT_RGTC2_UNORM , rgtc, 4, 4, x128, , , , xy01, rgb |
PIPE_FORMAT_RGTC2_SNORM , rgtc, 4, 4, x128, , , , xy01, rgb |
PIPE_FORMAT_LATC1_UNORM , rgtc, 4, 4, x64, , , , xxx1, rgb |
PIPE_FORMAT_LATC1_SNORM , rgtc, 4, 4, x64, , , , xxx1, rgb |
PIPE_FORMAT_LATC2_UNORM , rgtc, 4, 4, x128, , , , xxxy, rgb |
PIPE_FORMAT_LATC2_SNORM , rgtc, 4, 4, x128, , , , xxxy, rgb |
PIPE_FORMAT_ETC1_RGB8 , etc, 4, 4, x64, , , , xyz1, rgb |
# Straightforward D3D10-like formats (also used for |
# vertex buffer element description) |
# |
# See also: |
# - src/gallium/auxiliary/translate/translate_generic.c |
# - src/mesa/state_tracker/st_draw.c |
PIPE_FORMAT_R64_FLOAT , plain, 1, 1, f64 , , , , x001, rgb |
PIPE_FORMAT_R64G64_FLOAT , plain, 1, 1, f64 , f64 , , , xy01, rgb |
PIPE_FORMAT_R64G64B64_FLOAT , plain, 1, 1, f64 , f64 , f64 , , xyz1, rgb |
PIPE_FORMAT_R64G64B64A64_FLOAT , plain, 1, 1, f64 , f64 , f64 , f64 , xyzw, rgb |
PIPE_FORMAT_R32_FLOAT , plain, 1, 1, f32 , , , , x001, rgb |
PIPE_FORMAT_R32G32_FLOAT , plain, 1, 1, f32 , f32 , , , xy01, rgb |
PIPE_FORMAT_R32G32B32_FLOAT , plain, 1, 1, f32 , f32 , f32 , , xyz1, rgb |
PIPE_FORMAT_R32G32B32A32_FLOAT , plain, 1, 1, f32 , f32 , f32 , f32 , xyzw, rgb |
PIPE_FORMAT_R32_UNORM , plain, 1, 1, un32, , , , x001, rgb |
PIPE_FORMAT_R32G32_UNORM , plain, 1, 1, un32, un32, , , xy01, rgb |
PIPE_FORMAT_R32G32B32_UNORM , plain, 1, 1, un32, un32, un32, , xyz1, rgb |
PIPE_FORMAT_R32G32B32A32_UNORM , plain, 1, 1, un32, un32, un32, un32, xyzw, rgb |
PIPE_FORMAT_R32_USCALED , plain, 1, 1, u32 , , , , x001, rgb |
PIPE_FORMAT_R32G32_USCALED , plain, 1, 1, u32 , u32 , , , xy01, rgb |
PIPE_FORMAT_R32G32B32_USCALED , plain, 1, 1, u32 , u32 , u32 , , xyz1, rgb |
PIPE_FORMAT_R32G32B32A32_USCALED , plain, 1, 1, u32 , u32 , u32 , u32 , xyzw, rgb |
PIPE_FORMAT_R32_SNORM , plain, 1, 1, sn32, , , , x001, rgb |
PIPE_FORMAT_R32G32_SNORM , plain, 1, 1, sn32, sn32, , , xy01, rgb |
PIPE_FORMAT_R32G32B32_SNORM , plain, 1, 1, sn32, sn32, sn32, , xyz1, rgb |
PIPE_FORMAT_R32G32B32A32_SNORM , plain, 1, 1, sn32, sn32, sn32, sn32, xyzw, rgb |
PIPE_FORMAT_R32_SSCALED , plain, 1, 1, s32 , , , , x001, rgb |
PIPE_FORMAT_R32G32_SSCALED , plain, 1, 1, s32 , s32 , , , xy01, rgb |
PIPE_FORMAT_R32G32B32_SSCALED , plain, 1, 1, s32 , s32 , s32 , , xyz1, rgb |
PIPE_FORMAT_R32G32B32A32_SSCALED , plain, 1, 1, s32 , s32 , s32 , s32 , xyzw, rgb |
PIPE_FORMAT_R16_FLOAT , plain, 1, 1, f16 , , , , x001, rgb |
PIPE_FORMAT_R16G16_FLOAT , plain, 1, 1, f16 , f16 , , , xy01, rgb |
PIPE_FORMAT_R16G16B16_FLOAT , plain, 1, 1, f16 , f16 , f16 , , xyz1, rgb |
PIPE_FORMAT_R16G16B16A16_FLOAT , plain, 1, 1, f16 , f16 , f16 , f16 , xyzw, rgb |
PIPE_FORMAT_R16_UNORM , plain, 1, 1, un16, , , , x001, rgb |
PIPE_FORMAT_R16G16_UNORM , plain, 1, 1, un16, un16, , , xy01, rgb |
PIPE_FORMAT_R16G16B16_UNORM , plain, 1, 1, un16, un16, un16, , xyz1, rgb |
PIPE_FORMAT_R16G16B16A16_UNORM , plain, 1, 1, un16, un16, un16, un16, xyzw, rgb |
PIPE_FORMAT_R16_USCALED , plain, 1, 1, u16 , , , , x001, rgb |
PIPE_FORMAT_R16G16_USCALED , plain, 1, 1, u16 , u16 , , , xy01, rgb |
PIPE_FORMAT_R16G16B16_USCALED , plain, 1, 1, u16 , u16 , u16 , , xyz1, rgb |
PIPE_FORMAT_R16G16B16A16_USCALED , plain, 1, 1, u16 , u16 , u16 , u16 , xyzw, rgb |
PIPE_FORMAT_R16_SNORM , plain, 1, 1, sn16, , , , x001, rgb |
PIPE_FORMAT_R16G16_SNORM , plain, 1, 1, sn16, sn16, , , xy01, rgb |
PIPE_FORMAT_R16G16B16_SNORM , plain, 1, 1, sn16, sn16, sn16, , xyz1, rgb |
PIPE_FORMAT_R16G16B16A16_SNORM , plain, 1, 1, sn16, sn16, sn16, sn16, xyzw, rgb |
PIPE_FORMAT_R16_SSCALED , plain, 1, 1, s16 , , , , x001, rgb |
PIPE_FORMAT_R16G16_SSCALED , plain, 1, 1, s16 , s16 , , , xy01, rgb |
PIPE_FORMAT_R16G16B16_SSCALED , plain, 1, 1, s16 , s16 , s16 , , xyz1, rgb |
PIPE_FORMAT_R16G16B16A16_SSCALED , plain, 1, 1, s16 , s16 , s16 , s16 , xyzw, rgb |
PIPE_FORMAT_R8_UNORM , plain, 1, 1, un8 , , , , x001, rgb |
PIPE_FORMAT_R8G8_UNORM , plain, 1, 1, un8 , un8 , , , xy01, rgb |
PIPE_FORMAT_R8G8B8_UNORM , plain, 1, 1, un8 , un8 , un8 , , xyz1, rgb |
PIPE_FORMAT_R8G8B8A8_UNORM , plain, 1, 1, un8 , un8 , un8 , un8 , xyzw, rgb |
PIPE_FORMAT_R8_USCALED , plain, 1, 1, u8 , , , , x001, rgb |
PIPE_FORMAT_R8G8_USCALED , plain, 1, 1, u8 , u8 , , , xy01, rgb |
PIPE_FORMAT_R8G8B8_USCALED , plain, 1, 1, u8 , u8 , u8 , , xyz1, rgb |
PIPE_FORMAT_R8G8B8A8_USCALED , plain, 1, 1, u8 , u8 , u8 , u8 , xyzw, rgb |
PIPE_FORMAT_R8_SNORM , plain, 1, 1, sn8 , , , , x001, rgb |
PIPE_FORMAT_R8G8_SNORM , plain, 1, 1, sn8 , sn8 , , , xy01, rgb |
PIPE_FORMAT_R8G8B8_SNORM , plain, 1, 1, sn8 , sn8 , sn8 , , xyz1, rgb |
PIPE_FORMAT_R8G8B8A8_SNORM , plain, 1, 1, sn8 , sn8 , sn8 , sn8 , xyzw, rgb |
PIPE_FORMAT_R8_SSCALED , plain, 1, 1, s8 , , , , x001, rgb |
PIPE_FORMAT_R8G8_SSCALED , plain, 1, 1, s8 , s8 , , , xy01, rgb |
PIPE_FORMAT_R8G8B8_SSCALED , plain, 1, 1, s8 , s8 , s8 , , xyz1, rgb |
PIPE_FORMAT_R8G8B8A8_SSCALED , plain, 1, 1, s8 , s8 , s8 , s8 , xyzw, rgb |
# GL-specific vertex buffer element formats |
# A.k.a. GL_FIXED |
PIPE_FORMAT_R32_FIXED , plain, 1, 1, h32 , , , , x001, rgb |
PIPE_FORMAT_R32G32_FIXED , plain, 1, 1, h32 , h32 , , , xy01, rgb |
PIPE_FORMAT_R32G32B32_FIXED , plain, 1, 1, h32 , h32 , h32 , , xyz1, rgb |
PIPE_FORMAT_R32G32B32A32_FIXED , plain, 1, 1, h32 , h32 , h32 , h32 , xyzw, rgb |
# D3D9-specific vertex buffer element formats |
# See also: |
# - http://msdn.microsoft.com/en-us/library/bb172533.aspx |
# A.k.a. D3DDECLTYPE_UDEC3 |
PIPE_FORMAT_R10G10B10X2_USCALED , plain, 1, 1, u10 , u10 , u10 , x2 , xyz1, rgb |
# A.k.a. D3DDECLTYPE_DEC3N |
PIPE_FORMAT_R10G10B10X2_SNORM , plain, 1, 1, sn10, sn10, sn10 , x2 , xyz1, rgb |
PIPE_FORMAT_YV12 , other, 1, 1, x8 , x8 , x8 , x8 , xyzw, yuv |
PIPE_FORMAT_YV16 , other, 1, 1, x8 , x8 , x8 , x8 , xyzw, yuv |
PIPE_FORMAT_IYUV , other, 1, 1, x8 , x8 , x8 , x8 , xyzw, yuv |
PIPE_FORMAT_NV12 , other, 1, 1, x8 , x8 , x8 , x8 , xyzw, yuv |
PIPE_FORMAT_NV21 , other, 1, 1, x8 , x8 , x8 , x8 , xyzw, yuv |
# Usually used to implement IA44 and AI44 formats in video decoding |
PIPE_FORMAT_R4A4_UNORM , plain, 1, 1, un4 , un4 , , , y00x, rgb |
PIPE_FORMAT_A4R4_UNORM , plain, 1, 1, un4 , un4 , , , x00y, rgb |
PIPE_FORMAT_R8A8_UNORM , plain, 1, 1, un8 , un8 , , , x00y, rgb |
PIPE_FORMAT_A8R8_UNORM , plain, 1, 1, un8 , un8 , , , y00x, rgb |
# ARB_vertex_type_10_10_10_2_REV |
PIPE_FORMAT_R10G10B10A2_USCALED , plain, 1, 1, u10, u10, u10, u2, xyzw, rgb |
PIPE_FORMAT_R10G10B10A2_SSCALED , plain, 1, 1, s10, s10, s10, s2, xyzw, rgb |
PIPE_FORMAT_R10G10B10A2_SNORM , plain, 1, 1, sn10, sn10, sn10, sn2, xyzw, rgb |
PIPE_FORMAT_B10G10R10A2_USCALED , plain, 1, 1, u10, u10, u10, u2, zyxw, rgb |
PIPE_FORMAT_B10G10R10A2_SSCALED , plain, 1, 1, s10, s10, s10, s2, zyxw, rgb |
PIPE_FORMAT_B10G10R10A2_SNORM , plain, 1, 1, sn10, sn10, sn10, sn2, zyxw, rgb |
PIPE_FORMAT_R8_UINT , plain, 1, 1, up8, , , , x001, rgb |
PIPE_FORMAT_R8G8_UINT , plain, 1, 1, up8, up8, , , xy01, rgb |
PIPE_FORMAT_R8G8B8_UINT , plain, 1, 1, up8, up8, up8, , xyz1, rgb |
PIPE_FORMAT_R8G8B8A8_UINT , plain, 1, 1, up8, up8, up8, up8, xyzw, rgb |
PIPE_FORMAT_R8_SINT , plain, 1, 1, sp8, , , , x001, rgb |
PIPE_FORMAT_R8G8_SINT , plain, 1, 1, sp8, sp8, , , xy01, rgb |
PIPE_FORMAT_R8G8B8_SINT , plain, 1, 1, sp8, sp8, sp8, , xyz1, rgb |
PIPE_FORMAT_R8G8B8A8_SINT , plain, 1, 1, sp8, sp8, sp8, sp8, xyzw, rgb |
PIPE_FORMAT_R16_UINT , plain, 1, 1, up16, , , , x001, rgb |
PIPE_FORMAT_R16G16_UINT , plain, 1, 1, up16, up16, , , xy01, rgb |
PIPE_FORMAT_R16G16B16_UINT , plain, 1, 1, up16, up16, up16, , xyz1, rgb |
PIPE_FORMAT_R16G16B16A16_UINT , plain, 1, 1, up16, up16, up16, up16, xyzw, rgb |
PIPE_FORMAT_R16_SINT , plain, 1, 1, sp16, , , , x001, rgb |
PIPE_FORMAT_R16G16_SINT , plain, 1, 1, sp16, sp16, , , xy01, rgb |
PIPE_FORMAT_R16G16B16_SINT , plain, 1, 1, sp16, sp16, sp16, , xyz1, rgb |
PIPE_FORMAT_R16G16B16A16_SINT , plain, 1, 1, sp16, sp16, sp16, sp16, xyzw, rgb |
PIPE_FORMAT_R32_UINT , plain, 1, 1, up32, , , , x001, rgb |
PIPE_FORMAT_R32G32_UINT , plain, 1, 1, up32, up32, , , xy01, rgb |
PIPE_FORMAT_R32G32B32_UINT , plain, 1, 1, up32, up32, up32, , xyz1, rgb |
PIPE_FORMAT_R32G32B32A32_UINT , plain, 1, 1, up32, up32, up32, up32, xyzw, rgb |
PIPE_FORMAT_R32_SINT , plain, 1, 1, sp32, , , , x001, rgb |
PIPE_FORMAT_R32G32_SINT , plain, 1, 1, sp32, sp32, , , xy01, rgb |
PIPE_FORMAT_R32G32B32_SINT , plain, 1, 1, sp32, sp32, sp32, , xyz1, rgb |
PIPE_FORMAT_R32G32B32A32_SINT , plain, 1, 1, sp32, sp32, sp32, sp32, xyzw, rgb |
PIPE_FORMAT_A8_UINT , plain, 1, 1, up8, , , , 000x, rgb |
PIPE_FORMAT_I8_UINT , plain, 1, 1, up8, , , , xxxx, rgb |
PIPE_FORMAT_L8_UINT , plain, 1, 1, up8, , , , xxx1, rgb |
PIPE_FORMAT_L8A8_UINT , plain, 1, 1, up8, up8, , , xxxy, rgb |
PIPE_FORMAT_A8_SINT , plain, 1, 1, sp8, , , , 000x, rgb |
PIPE_FORMAT_I8_SINT , plain, 1, 1, sp8, , , , xxxx, rgb |
PIPE_FORMAT_L8_SINT , plain, 1, 1, sp8, , , , xxx1, rgb |
PIPE_FORMAT_L8A8_SINT , plain, 1, 1, sp8, sp8, , , xxxy, rgb |
PIPE_FORMAT_A16_UINT , plain, 1, 1, up16, , , , 000x, rgb |
PIPE_FORMAT_I16_UINT , plain, 1, 1, up16, , , , xxxx, rgb |
PIPE_FORMAT_L16_UINT , plain, 1, 1, up16, , , , xxx1, rgb |
PIPE_FORMAT_L16A16_UINT , plain, 1, 1, up16, up16, , , xxxy, rgb |
PIPE_FORMAT_A16_SINT , plain, 1, 1, sp16, , , , 000x, rgb |
PIPE_FORMAT_I16_SINT , plain, 1, 1, sp16, , , , xxxx, rgb |
PIPE_FORMAT_L16_SINT , plain, 1, 1, sp16, , , , xxx1, rgb |
PIPE_FORMAT_L16A16_SINT , plain, 1, 1, sp16, sp16, , , xxxy, rgb |
PIPE_FORMAT_A32_UINT , plain, 1, 1, up32, , , , 000x, rgb |
PIPE_FORMAT_I32_UINT , plain, 1, 1, up32, , , , xxxx, rgb |
PIPE_FORMAT_L32_UINT , plain, 1, 1, up32, , , , xxx1, rgb |
PIPE_FORMAT_L32A32_UINT , plain, 1, 1, up32, up32, , , xxxy, rgb |
PIPE_FORMAT_A32_SINT , plain, 1, 1, sp32, , , , 000x, rgb |
PIPE_FORMAT_I32_SINT , plain, 1, 1, sp32, , , , xxxx, rgb |
PIPE_FORMAT_L32_SINT , plain, 1, 1, sp32, , , , xxx1, rgb |
PIPE_FORMAT_L32A32_SINT , plain, 1, 1, sp32, sp32, , , xxxy, rgb |
PIPE_FORMAT_B10G10R10A2_UINT , plain, 1, 1, up10, up10, up10, up2, zyxw, rgb |
PIPE_FORMAT_R8G8B8X8_SNORM , plain, 1, 1, sn8, sn8, sn8, x8, xyz1, rgb |
PIPE_FORMAT_R8G8B8X8_SRGB , plain, 1, 1, un8, un8, un8, x8, xyz1, srgb |
PIPE_FORMAT_R8G8B8X8_UINT , plain, 1, 1, up8, up8, up8, x8, xyz1, rgb |
PIPE_FORMAT_R8G8B8X8_SINT , plain, 1, 1, sp8, sp8, sp8, x8, xyz1, rgb |
PIPE_FORMAT_B10G10R10X2_UNORM , plain, 1, 1, un10, un10, un10, x2, zyx1, rgb |
PIPE_FORMAT_R16G16B16X16_UNORM , plain, 1, 1, un16, un16, un16, x16, xyz1, rgb |
PIPE_FORMAT_R16G16B16X16_SNORM , plain, 1, 1, sn16, sn16, sn16, x16, xyz1, rgb |
PIPE_FORMAT_R16G16B16X16_FLOAT , plain, 1, 1, f16, f16, f16, x16, xyz1, rgb |
PIPE_FORMAT_R16G16B16X16_UINT , plain, 1, 1, up16, up16, up16, x16, xyz1, rgb |
PIPE_FORMAT_R16G16B16X16_SINT , plain, 1, 1, sp16, sp16, sp16, x16, xyz1, rgb |
PIPE_FORMAT_R32G32B32X32_FLOAT , plain, 1, 1, f32, f32, f32, x32, xyz1, rgb |
PIPE_FORMAT_R32G32B32X32_UINT , plain, 1, 1, up32, up32, up32, x32, xyz1, rgb |
PIPE_FORMAT_R32G32B32X32_SINT , plain, 1, 1, sp32, sp32, sp32, x32, xyz1, rgb |
PIPE_FORMAT_R8A8_SNORM , plain, 1, 1, sn8 , sn8 , , , x00y, rgb |
PIPE_FORMAT_R16A16_UNORM , plain, 1, 1, un16 , un16 , , , x00y, rgb |
PIPE_FORMAT_R16A16_SNORM , plain, 1, 1, sn16 , sn16 , , , x00y, rgb |
PIPE_FORMAT_R16A16_FLOAT , plain, 1, 1, f16 , f16 , , , x00y, rgb |
PIPE_FORMAT_R32A32_FLOAT , plain, 1, 1, f32 , f32 , , , x00y, rgb |
PIPE_FORMAT_R8A8_UINT , plain, 1, 1, up8 , up8 , , , x00y, rgb |
PIPE_FORMAT_R8A8_SINT , plain, 1, 1, sp8 , sp8 , , , x00y, rgb |
PIPE_FORMAT_R16A16_UINT , plain, 1, 1, up16 , up16 , , , x00y, rgb |
PIPE_FORMAT_R16A16_SINT , plain, 1, 1, sp16 , sp16 , , , x00y, rgb |
PIPE_FORMAT_R32A32_UINT , plain, 1, 1, up32 , up32 , , , x00y, rgb |
PIPE_FORMAT_R32A32_SINT , plain, 1, 1, sp32 , sp32 , , , x00y, rgb |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_format.h |
---|
0,0 → 1,1196 |
/************************************************************************** |
* |
* Copyright 2009-2010 Vmware, Inc. |
* 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 VMWARE 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_FORMAT_H |
#define U_FORMAT_H |
#include "pipe/p_format.h" |
#include "pipe/p_defines.h" |
#include "util/u_debug.h" |
union pipe_color_union; |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* Describe how to pack/unpack pixels into/from the prescribed format. |
* |
* XXX: This could be renamed to something like util_format_pack, or broke down |
* in flags inside util_format_block that said exactly what we want. |
*/ |
enum util_format_layout { |
/** |
* Formats with util_format_block::width == util_format_block::height == 1 |
* that can be described as an ordinary data structure. |
*/ |
UTIL_FORMAT_LAYOUT_PLAIN = 0, |
/** |
* Formats with sub-sampled channels. |
* |
* This is for formats like YVYU where there is less than one sample per |
* pixel. |
*/ |
UTIL_FORMAT_LAYOUT_SUBSAMPLED = 3, |
/** |
* S3 Texture Compression formats. |
*/ |
UTIL_FORMAT_LAYOUT_S3TC = 4, |
/** |
* Red-Green Texture Compression formats. |
*/ |
UTIL_FORMAT_LAYOUT_RGTC = 5, |
/** |
* Ericsson Texture Compression |
*/ |
UTIL_FORMAT_LAYOUT_ETC = 6, |
/** |
* Everything else that doesn't fit in any of the above layouts. |
*/ |
UTIL_FORMAT_LAYOUT_OTHER = 7 |
}; |
struct util_format_block |
{ |
/** Block width in pixels */ |
unsigned width; |
/** Block height in pixels */ |
unsigned height; |
/** Block size in bits */ |
unsigned bits; |
}; |
enum util_format_type { |
UTIL_FORMAT_TYPE_VOID = 0, |
UTIL_FORMAT_TYPE_UNSIGNED = 1, |
UTIL_FORMAT_TYPE_SIGNED = 2, |
UTIL_FORMAT_TYPE_FIXED = 3, |
UTIL_FORMAT_TYPE_FLOAT = 4 |
}; |
enum util_format_swizzle { |
UTIL_FORMAT_SWIZZLE_X = 0, |
UTIL_FORMAT_SWIZZLE_Y = 1, |
UTIL_FORMAT_SWIZZLE_Z = 2, |
UTIL_FORMAT_SWIZZLE_W = 3, |
UTIL_FORMAT_SWIZZLE_0 = 4, |
UTIL_FORMAT_SWIZZLE_1 = 5, |
UTIL_FORMAT_SWIZZLE_NONE = 6, |
UTIL_FORMAT_SWIZZLE_MAX = 7 /**< Number of enums counter (must be last) */ |
}; |
enum util_format_colorspace { |
UTIL_FORMAT_COLORSPACE_RGB = 0, |
UTIL_FORMAT_COLORSPACE_SRGB = 1, |
UTIL_FORMAT_COLORSPACE_YUV = 2, |
UTIL_FORMAT_COLORSPACE_ZS = 3 |
}; |
struct util_format_channel_description |
{ |
unsigned type:5; /**< UTIL_FORMAT_TYPE_x */ |
unsigned normalized:1; |
unsigned pure_integer:1; |
unsigned size:9; /**< bits per channel */ |
unsigned shift:16; /** number of bits from lsb */ |
}; |
struct util_format_description |
{ |
enum pipe_format format; |
const char *name; |
/** |
* Short name, striped of the prefix, lower case. |
*/ |
const char *short_name; |
/** |
* Pixel block dimensions. |
*/ |
struct util_format_block block; |
enum util_format_layout layout; |
/** |
* The number of channels. |
*/ |
unsigned nr_channels:3; |
/** |
* Whether all channels have the same number of (whole) bytes and type. |
*/ |
unsigned is_array:1; |
/** |
* Whether the pixel format can be described as a bitfield structure. |
* |
* In particular: |
* - pixel depth must be 8, 16, or 32 bits; |
* - all channels must be unsigned, signed, or void |
*/ |
unsigned is_bitmask:1; |
/** |
* Whether channels have mixed types (ignoring UTIL_FORMAT_TYPE_VOID). |
*/ |
unsigned is_mixed:1; |
/** |
* Input channel description, in the order XYZW. |
* |
* Only valid for UTIL_FORMAT_LAYOUT_PLAIN formats. |
* |
* If each channel is accessed as an individual N-byte value, X is always |
* at the lowest address in memory, Y is always next, and so on. For all |
* currently-defined formats, the N-byte value has native endianness. |
* |
* If instead a group of channels is accessed as a single N-byte value, |
* the order of the channels within that value depends on endianness. |
* For big-endian targets, X is the most significant subvalue, |
* otherwise it is the least significant one. |
* |
* For example, if X is 8 bits and Y is 24 bits, the memory order is: |
* |
* 0 1 2 3 |
* little-endian: X Yl Ym Yu (l = lower, m = middle, u = upper) |
* big-endian: X Yu Ym Yl |
* |
* If X is 5 bits, Y is 5 bits, Z is 5 bits and W is 1 bit, the layout is: |
* |
* 0 1 |
* msb lsb msb lsb |
* little-endian: YYYXXXXX WZZZZZYY |
* big-endian: XXXXXYYY YYZZZZZW |
*/ |
struct util_format_channel_description channel[4]; |
/** |
* Output channel swizzle. |
* |
* The order is either: |
* - RGBA |
* - YUV(A) |
* - ZS |
* depending on the colorspace. |
*/ |
unsigned char swizzle[4]; |
/** |
* Colorspace transformation. |
*/ |
enum util_format_colorspace colorspace; |
/** |
* Unpack pixel blocks to R8G8B8A8_UNORM. |
* Note: strides are in bytes. |
* |
* Only defined for non-depth-stencil formats. |
*/ |
void |
(*unpack_rgba_8unorm)(uint8_t *dst, unsigned dst_stride, |
const uint8_t *src, unsigned src_stride, |
unsigned width, unsigned height); |
/** |
* Pack pixel blocks from R8G8B8A8_UNORM. |
* Note: strides are in bytes. |
* |
* Only defined for non-depth-stencil formats. |
*/ |
void |
(*pack_rgba_8unorm)(uint8_t *dst, unsigned dst_stride, |
const uint8_t *src, unsigned src_stride, |
unsigned width, unsigned height); |
/** |
* Fetch a single pixel (i, j) from a block. |
* |
* XXX: Only defined for a very few select formats. |
*/ |
void |
(*fetch_rgba_8unorm)(uint8_t *dst, |
const uint8_t *src, |
unsigned i, unsigned j); |
/** |
* Unpack pixel blocks to R32G32B32A32_FLOAT. |
* Note: strides are in bytes. |
* |
* Only defined for non-depth-stencil formats. |
*/ |
void |
(*unpack_rgba_float)(float *dst, unsigned dst_stride, |
const uint8_t *src, unsigned src_stride, |
unsigned width, unsigned height); |
/** |
* Pack pixel blocks from R32G32B32A32_FLOAT. |
* Note: strides are in bytes. |
* |
* Only defined for non-depth-stencil formats. |
*/ |
void |
(*pack_rgba_float)(uint8_t *dst, unsigned dst_stride, |
const float *src, unsigned src_stride, |
unsigned width, unsigned height); |
/** |
* Fetch a single pixel (i, j) from a block. |
* |
* Only defined for non-depth-stencil and non-integer formats. |
*/ |
void |
(*fetch_rgba_float)(float *dst, |
const uint8_t *src, |
unsigned i, unsigned j); |
/** |
* Unpack pixels to Z32_UNORM. |
* Note: strides are in bytes. |
* |
* Only defined for depth formats. |
*/ |
void |
(*unpack_z_32unorm)(uint32_t *dst, unsigned dst_stride, |
const uint8_t *src, unsigned src_stride, |
unsigned width, unsigned height); |
/** |
* Pack pixels from Z32_FLOAT. |
* Note: strides are in bytes. |
* |
* Only defined for depth formats. |
*/ |
void |
(*pack_z_32unorm)(uint8_t *dst, unsigned dst_stride, |
const uint32_t *src, unsigned src_stride, |
unsigned width, unsigned height); |
/** |
* Unpack pixels to Z32_FLOAT. |
* Note: strides are in bytes. |
* |
* Only defined for depth formats. |
*/ |
void |
(*unpack_z_float)(float *dst, unsigned dst_stride, |
const uint8_t *src, unsigned src_stride, |
unsigned width, unsigned height); |
/** |
* Pack pixels from Z32_FLOAT. |
* Note: strides are in bytes. |
* |
* Only defined for depth formats. |
*/ |
void |
(*pack_z_float)(uint8_t *dst, unsigned dst_stride, |
const float *src, unsigned src_stride, |
unsigned width, unsigned height); |
/** |
* Unpack pixels to S8_UINT. |
* Note: strides are in bytes. |
* |
* Only defined for stencil formats. |
*/ |
void |
(*unpack_s_8uint)(uint8_t *dst, unsigned dst_stride, |
const uint8_t *src, unsigned src_stride, |
unsigned width, unsigned height); |
/** |
* Pack pixels from S8_UINT. |
* Note: strides are in bytes. |
* |
* Only defined for stencil formats. |
*/ |
void |
(*pack_s_8uint)(uint8_t *dst, unsigned dst_stride, |
const uint8_t *src, unsigned src_stride, |
unsigned width, unsigned height); |
/** |
* Unpack pixel blocks to R32G32B32A32_UINT. |
* Note: strides are in bytes. |
* |
* Only defined for INT formats. |
*/ |
void |
(*unpack_rgba_uint)(uint32_t *dst, unsigned dst_stride, |
const uint8_t *src, unsigned src_stride, |
unsigned width, unsigned height); |
void |
(*pack_rgba_uint)(uint8_t *dst, unsigned dst_stride, |
const uint32_t *src, unsigned src_stride, |
unsigned width, unsigned height); |
/** |
* Unpack pixel blocks to R32G32B32A32_SINT. |
* Note: strides are in bytes. |
* |
* Only defined for INT formats. |
*/ |
void |
(*unpack_rgba_sint)(int32_t *dst, unsigned dst_stride, |
const uint8_t *src, unsigned src_stride, |
unsigned width, unsigned height); |
void |
(*pack_rgba_sint)(uint8_t *dst, unsigned dst_stride, |
const int32_t *src, unsigned src_stride, |
unsigned width, unsigned height); |
/** |
* Fetch a single pixel (i, j) from a block. |
* |
* Only defined for unsigned (pure) integer formats. |
*/ |
void |
(*fetch_rgba_uint)(uint32_t *dst, |
const uint8_t *src, |
unsigned i, unsigned j); |
/** |
* Fetch a single pixel (i, j) from a block. |
* |
* Only defined for signed (pure) integer formats. |
*/ |
void |
(*fetch_rgba_sint)(int32_t *dst, |
const uint8_t *src, |
unsigned i, unsigned j); |
}; |
extern const struct util_format_description |
util_format_description_table[]; |
const struct util_format_description * |
util_format_description(enum pipe_format format); |
/* |
* Format query functions. |
*/ |
static INLINE const char * |
util_format_name(enum pipe_format format) |
{ |
const struct util_format_description *desc = util_format_description(format); |
assert(desc); |
if (!desc) { |
return "PIPE_FORMAT_???"; |
} |
return desc->name; |
} |
static INLINE const char * |
util_format_short_name(enum pipe_format format) |
{ |
const struct util_format_description *desc = util_format_description(format); |
assert(desc); |
if (!desc) { |
return "???"; |
} |
return desc->short_name; |
} |
/** |
* Whether this format is plain, see UTIL_FORMAT_LAYOUT_PLAIN for more info. |
*/ |
static INLINE boolean |
util_format_is_plain(enum pipe_format format) |
{ |
const struct util_format_description *desc = util_format_description(format); |
if (!format) { |
return FALSE; |
} |
return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN ? TRUE : FALSE; |
} |
static INLINE boolean |
util_format_is_compressed(enum pipe_format format) |
{ |
const struct util_format_description *desc = util_format_description(format); |
assert(desc); |
if (!desc) { |
return FALSE; |
} |
switch (desc->layout) { |
case UTIL_FORMAT_LAYOUT_S3TC: |
case UTIL_FORMAT_LAYOUT_RGTC: |
case UTIL_FORMAT_LAYOUT_ETC: |
/* XXX add other formats in the future */ |
return TRUE; |
default: |
return FALSE; |
} |
} |
static INLINE boolean |
util_format_is_s3tc(enum pipe_format format) |
{ |
const struct util_format_description *desc = util_format_description(format); |
assert(desc); |
if (!desc) { |
return FALSE; |
} |
return desc->layout == UTIL_FORMAT_LAYOUT_S3TC ? TRUE : FALSE; |
} |
static INLINE boolean |
util_format_is_srgb(enum pipe_format format) |
{ |
const struct util_format_description *desc = util_format_description(format); |
return desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB; |
} |
static INLINE boolean |
util_format_has_depth(const struct util_format_description *desc) |
{ |
return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS && |
desc->swizzle[0] != UTIL_FORMAT_SWIZZLE_NONE; |
} |
static INLINE boolean |
util_format_has_stencil(const struct util_format_description *desc) |
{ |
return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS && |
desc->swizzle[1] != UTIL_FORMAT_SWIZZLE_NONE; |
} |
static INLINE boolean |
util_format_is_depth_or_stencil(enum pipe_format format) |
{ |
const struct util_format_description *desc = util_format_description(format); |
assert(desc); |
if (!desc) { |
return FALSE; |
} |
return util_format_has_depth(desc) || |
util_format_has_stencil(desc); |
} |
static INLINE boolean |
util_format_is_depth_and_stencil(enum pipe_format format) |
{ |
const struct util_format_description *desc = util_format_description(format); |
assert(desc); |
if (!desc) { |
return FALSE; |
} |
return util_format_has_depth(desc) && |
util_format_has_stencil(desc); |
} |
/** |
* Return whether this is an RGBA, Z, S, or combined ZS format. |
* Useful for initializing pipe_blit_info::mask. |
*/ |
static INLINE unsigned |
util_format_get_mask(enum pipe_format format) |
{ |
const struct util_format_description *desc = |
util_format_description(format); |
if (!desc) |
return 0; |
if (util_format_has_depth(desc)) { |
if (util_format_has_stencil(desc)) { |
return PIPE_MASK_ZS; |
} else { |
return PIPE_MASK_Z; |
} |
} else { |
if (util_format_has_stencil(desc)) { |
return PIPE_MASK_S; |
} else { |
return PIPE_MASK_RGBA; |
} |
} |
} |
/** |
* Give the RGBA colormask of the channels that can be represented in this |
* format. |
* |
* That is, the channels whose values are preserved. |
*/ |
static INLINE unsigned |
util_format_colormask(const struct util_format_description *desc) |
{ |
unsigned colormask; |
unsigned chan; |
switch (desc->colorspace) { |
case UTIL_FORMAT_COLORSPACE_RGB: |
case UTIL_FORMAT_COLORSPACE_SRGB: |
case UTIL_FORMAT_COLORSPACE_YUV: |
colormask = 0; |
for (chan = 0; chan < 4; ++chan) { |
if (desc->swizzle[chan] < 4) { |
colormask |= (1 << chan); |
} |
} |
return colormask; |
case UTIL_FORMAT_COLORSPACE_ZS: |
return 0; |
default: |
assert(0); |
return 0; |
} |
} |
/** |
* Checks if color mask covers every channel for the specified format |
* |
* @param desc a format description to check colormask with |
* @param colormask a bit mask for channels, matches format of PIPE_MASK_RGBA |
*/ |
static INLINE boolean |
util_format_colormask_full(const struct util_format_description *desc, unsigned colormask) |
{ |
return (~colormask & util_format_colormask(desc)) == 0; |
} |
boolean |
util_format_is_float(enum pipe_format format); |
boolean |
util_format_has_alpha(enum pipe_format format); |
boolean |
util_format_is_luminance(enum pipe_format format); |
boolean |
util_format_is_luminance_alpha(enum pipe_format format); |
boolean |
util_format_is_intensity(enum pipe_format format); |
boolean |
util_format_is_pure_integer(enum pipe_format format); |
boolean |
util_format_is_pure_sint(enum pipe_format format); |
boolean |
util_format_is_pure_uint(enum pipe_format format); |
boolean |
util_format_is_snorm(enum pipe_format format); |
/** |
* Check if the src format can be blitted to the destination format with |
* a simple memcpy. For example, blitting from RGBA to RGBx is OK, but not |
* the reverse. |
*/ |
boolean |
util_is_format_compatible(const struct util_format_description *src_desc, |
const struct util_format_description *dst_desc); |
/** |
* Whether the format is supported by Gallium for the given bindings. |
* This covers S3TC textures and floating-point render targets. |
*/ |
boolean |
util_format_is_supported(enum pipe_format format, unsigned bind); |
/** |
* Whether this format is a rgab8 variant. |
* |
* That is, any format that matches the |
* |
* PIPE_FORMAT_?8?8?8?8_UNORM |
*/ |
static INLINE boolean |
util_format_is_rgba8_variant(const struct util_format_description *desc) |
{ |
unsigned chan; |
if(desc->block.width != 1 || |
desc->block.height != 1 || |
desc->block.bits != 32) |
return FALSE; |
for(chan = 0; chan < 4; ++chan) { |
if(desc->channel[chan].type != UTIL_FORMAT_TYPE_UNSIGNED && |
desc->channel[chan].type != UTIL_FORMAT_TYPE_VOID) |
return FALSE; |
if(desc->channel[chan].size != 8) |
return FALSE; |
} |
return TRUE; |
} |
/** |
* Return total bits needed for the pixel format per block. |
*/ |
static INLINE uint |
util_format_get_blocksizebits(enum pipe_format format) |
{ |
const struct util_format_description *desc = util_format_description(format); |
assert(desc); |
if (!desc) { |
return 0; |
} |
return desc->block.bits; |
} |
/** |
* Return bytes per block (not pixel) for the given format. |
*/ |
static INLINE uint |
util_format_get_blocksize(enum pipe_format format) |
{ |
uint bits = util_format_get_blocksizebits(format); |
assert(bits % 8 == 0); |
return bits / 8; |
} |
static INLINE uint |
util_format_get_blockwidth(enum pipe_format format) |
{ |
const struct util_format_description *desc = util_format_description(format); |
assert(desc); |
if (!desc) { |
return 1; |
} |
return desc->block.width; |
} |
static INLINE uint |
util_format_get_blockheight(enum pipe_format format) |
{ |
const struct util_format_description *desc = util_format_description(format); |
assert(desc); |
if (!desc) { |
return 1; |
} |
return desc->block.height; |
} |
static INLINE unsigned |
util_format_get_nblocksx(enum pipe_format format, |
unsigned x) |
{ |
unsigned blockwidth = util_format_get_blockwidth(format); |
return (x + blockwidth - 1) / blockwidth; |
} |
static INLINE unsigned |
util_format_get_nblocksy(enum pipe_format format, |
unsigned y) |
{ |
unsigned blockheight = util_format_get_blockheight(format); |
return (y + blockheight - 1) / blockheight; |
} |
static INLINE unsigned |
util_format_get_nblocks(enum pipe_format format, |
unsigned width, |
unsigned height) |
{ |
return util_format_get_nblocksx(format, width) * util_format_get_nblocksy(format, height); |
} |
static INLINE size_t |
util_format_get_stride(enum pipe_format format, |
unsigned width) |
{ |
return util_format_get_nblocksx(format, width) * util_format_get_blocksize(format); |
} |
static INLINE size_t |
util_format_get_2d_size(enum pipe_format format, |
size_t stride, |
unsigned height) |
{ |
return util_format_get_nblocksy(format, height) * stride; |
} |
static INLINE uint |
util_format_get_component_bits(enum pipe_format format, |
enum util_format_colorspace colorspace, |
uint component) |
{ |
const struct util_format_description *desc = util_format_description(format); |
enum util_format_colorspace desc_colorspace; |
assert(format); |
if (!format) { |
return 0; |
} |
assert(component < 4); |
/* Treat RGB and SRGB as equivalent. */ |
if (colorspace == UTIL_FORMAT_COLORSPACE_SRGB) { |
colorspace = UTIL_FORMAT_COLORSPACE_RGB; |
} |
if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) { |
desc_colorspace = UTIL_FORMAT_COLORSPACE_RGB; |
} else { |
desc_colorspace = desc->colorspace; |
} |
if (desc_colorspace != colorspace) { |
return 0; |
} |
switch (desc->swizzle[component]) { |
case UTIL_FORMAT_SWIZZLE_X: |
return desc->channel[0].size; |
case UTIL_FORMAT_SWIZZLE_Y: |
return desc->channel[1].size; |
case UTIL_FORMAT_SWIZZLE_Z: |
return desc->channel[2].size; |
case UTIL_FORMAT_SWIZZLE_W: |
return desc->channel[3].size; |
default: |
return 0; |
} |
} |
/** |
* 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) |
{ |
switch (format) { |
case PIPE_FORMAT_L8_UNORM: |
return PIPE_FORMAT_L8_SRGB; |
case PIPE_FORMAT_L8A8_UNORM: |
return PIPE_FORMAT_L8A8_SRGB; |
case PIPE_FORMAT_R8G8B8_UNORM: |
return PIPE_FORMAT_R8G8B8_SRGB; |
case PIPE_FORMAT_A8B8G8R8_UNORM: |
return PIPE_FORMAT_A8B8G8R8_SRGB; |
case PIPE_FORMAT_X8B8G8R8_UNORM: |
return PIPE_FORMAT_X8B8G8R8_SRGB; |
case PIPE_FORMAT_B8G8R8A8_UNORM: |
return PIPE_FORMAT_B8G8R8A8_SRGB; |
case PIPE_FORMAT_B8G8R8X8_UNORM: |
return PIPE_FORMAT_B8G8R8X8_SRGB; |
case PIPE_FORMAT_A8R8G8B8_UNORM: |
return PIPE_FORMAT_A8R8G8B8_SRGB; |
case PIPE_FORMAT_X8R8G8B8_UNORM: |
return PIPE_FORMAT_X8R8G8B8_SRGB; |
case PIPE_FORMAT_R8G8B8A8_UNORM: |
return PIPE_FORMAT_R8G8B8A8_SRGB; |
case PIPE_FORMAT_R8G8B8X8_UNORM: |
return PIPE_FORMAT_R8G8B8X8_SRGB; |
case PIPE_FORMAT_DXT1_RGB: |
return PIPE_FORMAT_DXT1_SRGB; |
case PIPE_FORMAT_DXT1_RGBA: |
return PIPE_FORMAT_DXT1_SRGBA; |
case PIPE_FORMAT_DXT3_RGBA: |
return PIPE_FORMAT_DXT3_SRGBA; |
case PIPE_FORMAT_DXT5_RGBA: |
return PIPE_FORMAT_DXT5_SRGBA; |
default: |
return PIPE_FORMAT_NONE; |
} |
} |
/** |
* 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_R8G8B8A8_SRGB: |
return PIPE_FORMAT_R8G8B8A8_UNORM; |
case PIPE_FORMAT_R8G8B8X8_SRGB: |
return PIPE_FORMAT_R8G8B8X8_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; |
} |
} |
/** |
* Given a depth-stencil format, return the corresponding stencil-only format. |
* For stencil-only formats, return the format unchanged. |
*/ |
static INLINE enum pipe_format |
util_format_stencil_only(enum pipe_format format) |
{ |
switch (format) { |
/* mask out the depth component */ |
case PIPE_FORMAT_Z24_UNORM_S8_UINT: |
return PIPE_FORMAT_X24S8_UINT; |
case PIPE_FORMAT_S8_UINT_Z24_UNORM: |
return PIPE_FORMAT_S8X24_UINT; |
case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: |
return PIPE_FORMAT_X32_S8X24_UINT; |
/* stencil only formats */ |
case PIPE_FORMAT_X24S8_UINT: |
case PIPE_FORMAT_S8X24_UINT: |
case PIPE_FORMAT_X32_S8X24_UINT: |
case PIPE_FORMAT_S8_UINT: |
return format; |
default: |
assert(0); |
return PIPE_FORMAT_NONE; |
} |
} |
/** |
* Converts PIPE_FORMAT_*I* to PIPE_FORMAT_*R*. |
* This is identity for non-intensity formats. |
*/ |
static INLINE enum pipe_format |
util_format_intensity_to_red(enum pipe_format format) |
{ |
switch (format) { |
case PIPE_FORMAT_I8_UNORM: |
return PIPE_FORMAT_R8_UNORM; |
case PIPE_FORMAT_I8_SNORM: |
return PIPE_FORMAT_R8_SNORM; |
case PIPE_FORMAT_I16_UNORM: |
return PIPE_FORMAT_R16_UNORM; |
case PIPE_FORMAT_I16_SNORM: |
return PIPE_FORMAT_R16_SNORM; |
case PIPE_FORMAT_I16_FLOAT: |
return PIPE_FORMAT_R16_FLOAT; |
case PIPE_FORMAT_I32_FLOAT: |
return PIPE_FORMAT_R32_FLOAT; |
case PIPE_FORMAT_I8_UINT: |
return PIPE_FORMAT_R8_UINT; |
case PIPE_FORMAT_I8_SINT: |
return PIPE_FORMAT_R8_SINT; |
case PIPE_FORMAT_I16_UINT: |
return PIPE_FORMAT_R16_UINT; |
case PIPE_FORMAT_I16_SINT: |
return PIPE_FORMAT_R16_SINT; |
case PIPE_FORMAT_I32_UINT: |
return PIPE_FORMAT_R32_UINT; |
case PIPE_FORMAT_I32_SINT: |
return PIPE_FORMAT_R32_SINT; |
default: |
assert(!util_format_is_intensity(format)); |
return format; |
} |
} |
/** |
* Converts PIPE_FORMAT_*L* to PIPE_FORMAT_*R*. |
* This is identity for non-luminance formats. |
*/ |
static INLINE enum pipe_format |
util_format_luminance_to_red(enum pipe_format format) |
{ |
switch (format) { |
case PIPE_FORMAT_L8_UNORM: |
return PIPE_FORMAT_R8_UNORM; |
case PIPE_FORMAT_L8_SNORM: |
return PIPE_FORMAT_R8_SNORM; |
case PIPE_FORMAT_L16_UNORM: |
return PIPE_FORMAT_R16_UNORM; |
case PIPE_FORMAT_L16_SNORM: |
return PIPE_FORMAT_R16_SNORM; |
case PIPE_FORMAT_L16_FLOAT: |
return PIPE_FORMAT_R16_FLOAT; |
case PIPE_FORMAT_L32_FLOAT: |
return PIPE_FORMAT_R32_FLOAT; |
case PIPE_FORMAT_L8_UINT: |
return PIPE_FORMAT_R8_UINT; |
case PIPE_FORMAT_L8_SINT: |
return PIPE_FORMAT_R8_SINT; |
case PIPE_FORMAT_L16_UINT: |
return PIPE_FORMAT_R16_UINT; |
case PIPE_FORMAT_L16_SINT: |
return PIPE_FORMAT_R16_SINT; |
case PIPE_FORMAT_L32_UINT: |
return PIPE_FORMAT_R32_UINT; |
case PIPE_FORMAT_L32_SINT: |
return PIPE_FORMAT_R32_SINT; |
case PIPE_FORMAT_LATC1_UNORM: |
return PIPE_FORMAT_RGTC1_UNORM; |
case PIPE_FORMAT_LATC1_SNORM: |
return PIPE_FORMAT_RGTC1_SNORM; |
case PIPE_FORMAT_L4A4_UNORM: |
/* XXX A4R4 is defined as x00y in u_format.csv */ |
return PIPE_FORMAT_A4R4_UNORM; |
case PIPE_FORMAT_L8A8_UNORM: |
return PIPE_FORMAT_R8A8_UNORM; |
case PIPE_FORMAT_L8A8_SNORM: |
return PIPE_FORMAT_R8A8_SNORM; |
case PIPE_FORMAT_L16A16_UNORM: |
return PIPE_FORMAT_R16A16_UNORM; |
case PIPE_FORMAT_L16A16_SNORM: |
return PIPE_FORMAT_R16A16_SNORM; |
case PIPE_FORMAT_L16A16_FLOAT: |
return PIPE_FORMAT_R16A16_FLOAT; |
case PIPE_FORMAT_L32A32_FLOAT: |
return PIPE_FORMAT_R32A32_FLOAT; |
case PIPE_FORMAT_L8A8_UINT: |
return PIPE_FORMAT_R8A8_UINT; |
case PIPE_FORMAT_L8A8_SINT: |
return PIPE_FORMAT_R8A8_SINT; |
case PIPE_FORMAT_L16A16_UINT: |
return PIPE_FORMAT_R16A16_UINT; |
case PIPE_FORMAT_L16A16_SINT: |
return PIPE_FORMAT_R16A16_SINT; |
case PIPE_FORMAT_L32A32_UINT: |
return PIPE_FORMAT_R32A32_UINT; |
case PIPE_FORMAT_L32A32_SINT: |
return PIPE_FORMAT_R32A32_SINT; |
/* We don't have compressed red-alpha variants for these. */ |
case PIPE_FORMAT_LATC2_UNORM: |
case PIPE_FORMAT_LATC2_SNORM: |
return PIPE_FORMAT_NONE; |
default: |
assert(!util_format_is_luminance(format) && |
!util_format_is_luminance_alpha(format)); |
return format; |
} |
} |
/** |
* Return the number of components stored. |
* Formats with block size != 1x1 will always have 1 component (the block). |
*/ |
static INLINE unsigned |
util_format_get_nr_components(enum pipe_format format) |
{ |
const struct util_format_description *desc = util_format_description(format); |
return desc->nr_channels; |
} |
/** |
* Return the index of the first non-void channel |
* -1 if no non-void channels |
*/ |
static INLINE int |
util_format_get_first_non_void_channel(enum pipe_format format) |
{ |
const struct util_format_description *desc = util_format_description(format); |
int i; |
for (i = 0; i < 4; i++) |
if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) |
break; |
if (i == 4) |
return -1; |
return i; |
} |
/* |
* Format access functions. |
*/ |
void |
util_format_read_4f(enum pipe_format format, |
float *dst, unsigned dst_stride, |
const void *src, unsigned src_stride, |
unsigned x, unsigned y, unsigned w, unsigned h); |
void |
util_format_write_4f(enum pipe_format format, |
const float *src, unsigned src_stride, |
void *dst, unsigned dst_stride, |
unsigned x, unsigned y, unsigned w, unsigned h); |
void |
util_format_read_4ub(enum pipe_format format, |
uint8_t *dst, unsigned dst_stride, |
const void *src, unsigned src_stride, |
unsigned x, unsigned y, unsigned w, unsigned h); |
void |
util_format_write_4ub(enum pipe_format format, |
const uint8_t *src, unsigned src_stride, |
void *dst, unsigned dst_stride, |
unsigned x, unsigned y, unsigned w, unsigned h); |
void |
util_format_read_4ui(enum pipe_format format, |
unsigned *dst, unsigned dst_stride, |
const void *src, unsigned src_stride, |
unsigned x, unsigned y, unsigned w, unsigned h); |
void |
util_format_write_4ui(enum pipe_format format, |
const unsigned int *src, unsigned src_stride, |
void *dst, unsigned dst_stride, |
unsigned x, unsigned y, unsigned w, unsigned h); |
void |
util_format_read_4i(enum pipe_format format, |
int *dst, unsigned dst_stride, |
const void *src, unsigned src_stride, |
unsigned x, unsigned y, unsigned w, unsigned h); |
void |
util_format_write_4i(enum pipe_format format, |
const int *src, unsigned src_stride, |
void *dst, unsigned dst_stride, |
unsigned x, unsigned y, unsigned w, unsigned h); |
/* |
* Generic format conversion; |
*/ |
boolean |
util_format_fits_8unorm(const struct util_format_description *format_desc); |
void |
util_format_translate(enum pipe_format dst_format, |
void *dst, unsigned dst_stride, |
unsigned dst_x, unsigned dst_y, |
enum pipe_format src_format, |
const void *src, unsigned src_stride, |
unsigned src_x, unsigned src_y, |
unsigned width, unsigned height); |
/* |
* Swizzle operations. |
*/ |
/* Compose two sets of swizzles. |
* If V is a 4D vector and the function parameters represent functions that |
* swizzle vector components, this holds: |
* swz2(swz1(V)) = dst(V) |
*/ |
void util_format_compose_swizzles(const unsigned char swz1[4], |
const unsigned char swz2[4], |
unsigned char dst[4]); |
/* Apply the swizzle provided in \param swz (which is one of PIPE_SWIZZLE_x) |
* to \param src and store the result in \param dst. |
* \param is_integer determines the value written for PIPE_SWIZZLE_ONE. |
*/ |
void util_format_apply_color_swizzle(union pipe_color_union *dst, |
const union pipe_color_union *src, |
const unsigned char swz[4], |
const boolean is_integer); |
void util_format_swizzle_4f(float *dst, const float *src, |
const unsigned char swz[4]); |
void util_format_unswizzle_4f(float *dst, const float *src, |
const unsigned char swz[4]); |
#ifdef __cplusplus |
} // extern "C" { |
#endif |
#endif /* ! U_FORMAT_H */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_format_etc.c |
---|
0,0 → 1,81 |
#include "pipe/p_compiler.h" |
#include "util/u_debug.h" |
#include "util/u_math.h" |
#include "u_format_etc.h" |
/* define etc1_parse_block and etc. */ |
#define UINT8_TYPE uint8_t |
#define TAG(x) x |
#include "../../../mesa/main/texcompress_etc_tmp.h" |
#undef TAG |
#undef UINT8_TYPE |
void |
util_format_etc1_rgb8_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
etc1_unpack_rgba8888(dst_row, dst_stride, src_row, src_stride, width, height); |
} |
void |
util_format_etc1_rgb8_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
assert(0); |
} |
void |
util_format_etc1_rgb8_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
const unsigned bw = 4, bh = 4, bs = 8, comps = 4; |
struct etc1_block block; |
unsigned x, y, i, j; |
for (y = 0; y < height; y += bh) { |
const uint8_t *src = src_row; |
for (x = 0; x < width; x+= bw) { |
etc1_parse_block(&block, src); |
for (j = 0; j < bh; j++) { |
float *dst = dst_row + (y + j) * dst_stride / sizeof(*dst_row) + x * comps; |
uint8_t tmp[3]; |
for (i = 0; i < bw; i++) { |
etc1_fetch_texel(&block, i, j, tmp); |
dst[0] = ubyte_to_float(tmp[0]); |
dst[1] = ubyte_to_float(tmp[1]); |
dst[2] = ubyte_to_float(tmp[2]); |
dst[3] = 1.0f; |
dst += comps; |
} |
} |
src += bs; |
} |
src_row += src_stride; |
} |
} |
void |
util_format_etc1_rgb8_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
assert(0); |
} |
void |
util_format_etc1_rgb8_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
const unsigned bw = 4, bh = 4; |
struct etc1_block block; |
uint8_t tmp[3]; |
assert(i < bw && j < bh); |
etc1_parse_block(&block, src); |
etc1_fetch_texel(&block, i, j, tmp); |
dst[0] = ubyte_to_float(tmp[0]); |
dst[1] = ubyte_to_float(tmp[1]); |
dst[2] = ubyte_to_float(tmp[2]); |
dst[3] = 1.0f; |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_format_etc.h |
---|
0,0 → 1,46 |
/************************************************************************** |
* |
* Copyright 2011 LunarG, Inc. |
* 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 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 |
* THE COPYRIGHT HOLDERS, 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. |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
**************************************************************************/ |
#ifndef U_FORMAT_ETC1_H_ |
#define U_FORMAT_ETC1_H_ |
void |
util_format_etc1_rgb8_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_etc1_rgb8_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_etc1_rgb8_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_etc1_rgb8_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_etc1_rgb8_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j); |
#endif /* U_FORMAT_ETC1_H_ */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_format_latc.c |
---|
0,0 → 1,332 |
/************************************************************************** |
* |
* Copyright (C) 2011 Red Hat Inc. |
* |
* 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, sublicense, |
* 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 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 NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS 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 <stdio.h> |
#include "u_math.h" |
#include "u_format.h" |
#include "u_format_rgtc.h" |
#include "u_format_latc.h" |
static void u_format_unsigned_encode_rgtc_ubyte(uint8_t *blkaddr, uint8_t srccolors[4][4], |
int numxpixels, int numypixels); |
static void u_format_unsigned_fetch_texel_rgtc(unsigned srcRowStride, const uint8_t *pixdata, |
unsigned i, unsigned j, uint8_t *value, unsigned comps); |
static void u_format_signed_encode_rgtc_ubyte(int8_t *blkaddr, int8_t srccolors[4][4], |
int numxpixels, int numypixels); |
static void u_format_signed_fetch_texel_rgtc(unsigned srcRowStride, const int8_t *pixdata, |
unsigned i, unsigned j, int8_t *value, unsigned comps); |
void |
util_format_latc1_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
/* Fix warnings here: */ |
(void) u_format_unsigned_encode_rgtc_ubyte; |
(void) u_format_signed_encode_rgtc_ubyte; |
u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 1); |
dst[1] = dst[0]; |
dst[2] = dst[0]; |
dst[3] = 255; |
} |
void |
util_format_latc1_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_rgtc1_unorm_unpack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height); |
} |
void |
util_format_latc1_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, |
unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_rgtc1_unorm_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height); |
} |
void |
util_format_latc1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
unsigned x, y, i, j; |
int block_size = 8; |
for(y = 0; y < height; y += 4) { |
const uint8_t *src = src_row; |
for(x = 0; x < width; x += 4) { |
for(j = 0; j < 4; ++j) { |
for(i = 0; i < 4; ++i) { |
float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; |
uint8_t tmp_r; |
u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1); |
dst[0] = |
dst[1] = |
dst[2] = ubyte_to_float(tmp_r); |
dst[3] = 1.0; |
} |
} |
src += block_size; |
} |
src_row += src_stride; |
} |
} |
void |
util_format_latc1_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_rgtc1_unorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height); |
} |
void |
util_format_latc1_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
uint8_t tmp_r; |
u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1); |
dst[0] = |
dst[1] = |
dst[2] = ubyte_to_float(tmp_r); |
dst[3] = 1.0; |
} |
void |
util_format_latc1_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
fprintf(stderr,"%s\n", __func__); |
} |
void |
util_format_latc1_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
fprintf(stderr,"%s\n", __func__); |
} |
void |
util_format_latc1_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
fprintf(stderr,"%s\n", __func__); |
} |
void |
util_format_latc1_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_rgtc1_snorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height); |
} |
void |
util_format_latc1_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
unsigned x, y, i, j; |
int block_size = 8; |
for(y = 0; y < height; y += 4) { |
const int8_t *src = (int8_t *)src_row; |
for(x = 0; x < width; x += 4) { |
for(j = 0; j < 4; ++j) { |
for(i = 0; i < 4; ++i) { |
float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; |
int8_t tmp_r; |
u_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1); |
dst[0] = |
dst[1] = |
dst[2] = byte_to_float_tex(tmp_r); |
dst[3] = 1.0; |
} |
} |
src += block_size; |
} |
src_row += src_stride; |
} |
} |
void |
util_format_latc1_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
int8_t tmp_r; |
u_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 1); |
dst[0] = |
dst[1] = |
dst[2] = byte_to_float_tex(tmp_r); |
dst[3] = 1.0; |
} |
void |
util_format_latc2_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 2); |
dst[1] = dst[0]; |
dst[2] = dst[0]; |
u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, dst + 3, 2); |
} |
void |
util_format_latc2_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_rgtc2_unorm_unpack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height); |
} |
void |
util_format_latc2_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_rgtc2_unorm_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, width, height); |
} |
void |
util_format_latc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_rxtc2_unorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 3); |
} |
void |
util_format_latc2_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
unsigned x, y, i, j; |
int block_size = 16; |
for(y = 0; y < height; y += 4) { |
const uint8_t *src = src_row; |
for(x = 0; x < width; x += 4) { |
for(j = 0; j < 4; ++j) { |
for(i = 0; i < 4; ++i) { |
float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; |
uint8_t tmp_r, tmp_g; |
u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2); |
u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2); |
dst[0] = |
dst[1] = |
dst[2] = ubyte_to_float(tmp_r); |
dst[3] = ubyte_to_float(tmp_g); |
} |
} |
src += block_size; |
} |
src_row += src_stride; |
} |
} |
void |
util_format_latc2_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
uint8_t tmp_r, tmp_g; |
u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2); |
u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2); |
dst[0] = |
dst[1] = |
dst[2] = ubyte_to_float(tmp_r); |
dst[3] = ubyte_to_float(tmp_g); |
} |
void |
util_format_latc2_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
fprintf(stderr,"%s\n", __func__); |
} |
void |
util_format_latc2_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
fprintf(stderr,"%s\n", __func__); |
} |
void |
util_format_latc2_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
fprintf(stderr,"%s\n", __func__); |
} |
void |
util_format_latc2_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
unsigned x, y, i, j; |
int block_size = 16; |
for(y = 0; y < height; y += 4) { |
const int8_t *src = (int8_t *)src_row; |
for(x = 0; x < width; x += 4) { |
for(j = 0; j < 4; ++j) { |
for(i = 0; i < 4; ++i) { |
float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; |
int8_t tmp_r, tmp_g; |
u_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2); |
u_format_signed_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2); |
dst[0] = |
dst[1] = |
dst[2] = byte_to_float_tex(tmp_r); |
dst[3] = byte_to_float_tex(tmp_g); |
} |
} |
src += block_size; |
} |
src_row += src_stride; |
} |
} |
void |
util_format_latc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_rxtc2_snorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 3); |
} |
void |
util_format_latc2_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
int8_t tmp_r, tmp_g; |
u_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 2); |
u_format_signed_fetch_texel_rgtc(0, (int8_t *)src + 8, i, j, &tmp_g, 2); |
dst[0] = |
dst[1] = |
dst[2] = byte_to_float_tex(tmp_r); |
dst[3] = byte_to_float_tex(tmp_g); |
} |
#define TAG(x) u_format_unsigned_##x |
#define TYPE uint8_t |
#define T_MIN 0 |
#define T_MAX 255 |
#include "../../../mesa/main/texcompress_rgtc_tmp.h" |
#undef TYPE |
#undef TAG |
#undef T_MIN |
#undef T_MAX |
#define TAG(x) u_format_signed_##x |
#define TYPE int8_t |
#define T_MIN (int8_t)-128 |
#define T_MAX (int8_t)127 |
#include "../../../mesa/main/texcompress_rgtc_tmp.h" |
#undef TYPE |
#undef TAG |
#undef T_MIN |
#undef T_MAX |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_format_latc.h |
---|
0,0 → 1,108 |
/************************************************************************** |
* |
* Copyright 2011 Red Hat Inc. |
* 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 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 |
* THE COPYRIGHT HOLDERS, 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. |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
**************************************************************************/ |
#ifndef U_FORMAT_LATC_H_ |
#define U_FORMAT_LATC_H_ |
void |
util_format_latc1_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j); |
void |
util_format_latc1_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_latc1_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_latc1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_latc1_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_latc1_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j); |
void |
util_format_latc1_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j); |
void |
util_format_latc1_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_latc1_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_latc1_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_latc1_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_latc1_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j); |
void |
util_format_latc2_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j); |
void |
util_format_latc2_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_latc2_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_latc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_latc2_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_latc2_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j); |
void |
util_format_latc2_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j); |
void |
util_format_latc2_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_latc2_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_latc2_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_latc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_latc2_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j); |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_format_other.c |
---|
0,0 → 1,472 |
/************************************************************************** |
* |
* Copyright 2010 VMware, Inc. |
* 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 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 |
* THE COPYRIGHT HOLDERS, 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. |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
**************************************************************************/ |
#include "u_math.h" |
#include "u_format_other.h" |
#include "u_format_rgb9e5.h" |
#include "u_format_r11g11b10f.h" |
void |
util_format_r9g9b9e5_float_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; y += 1) { |
float *dst = dst_row; |
const uint8_t *src = src_row; |
for(x = 0; x < width; x += 1) { |
uint32_t value = *(const uint32_t *)src; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
rgb9e5_to_float3(value, dst); |
dst[3] = 1; /* a */ |
src += 4; |
dst += 4; |
} |
src_row += src_stride; |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_r9g9b9e5_float_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; y += 1) { |
const float *src = src_row; |
uint8_t *dst = dst_row; |
for(x = 0; x < width; x += 1) { |
uint32_t value = float3_to_rgb9e5(src); |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*(uint32_t *)dst = value; |
src += 4; |
dst += 4; |
} |
dst_row += dst_stride; |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_r9g9b9e5_float_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j) |
{ |
uint32_t value = *(const uint32_t *)src; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
rgb9e5_to_float3(value, dst); |
dst[3] = 1; /* a */ |
} |
void |
util_format_r9g9b9e5_float_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
float p[3]; |
for(y = 0; y < height; y += 1) { |
uint8_t *dst = dst_row; |
const uint8_t *src = src_row; |
for(x = 0; x < width; x += 1) { |
uint32_t value = *(const uint32_t *)src; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
rgb9e5_to_float3(value, p); |
dst[0] = float_to_ubyte(p[0]); /* r */ |
dst[1] = float_to_ubyte(p[1]); /* g */ |
dst[2] = float_to_ubyte(p[2]); /* b */ |
dst[3] = 255; /* a */ |
src += 4; |
dst += 4; |
} |
src_row += src_stride; |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_r9g9b9e5_float_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
float p[3]; |
for(y = 0; y < height; y += 1) { |
const uint8_t *src = src_row; |
uint8_t *dst = dst_row; |
for(x = 0; x < width; x += 1) { |
uint32_t value; |
p[0] = ubyte_to_float(src[0]); |
p[1] = ubyte_to_float(src[1]); |
p[2] = ubyte_to_float(src[2]); |
value = float3_to_rgb9e5(p); |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*(uint32_t *)dst = value; |
src += 4; |
dst += 4; |
} |
dst_row += dst_stride; |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_r11g11b10_float_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; y += 1) { |
float *dst = dst_row; |
const uint8_t *src = src_row; |
for(x = 0; x < width; x += 1) { |
uint32_t value = *(const uint32_t *)src; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
r11g11b10f_to_float3(value, dst); |
dst[3] = 1; /* a */ |
src += 4; |
dst += 4; |
} |
src_row += src_stride; |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_r11g11b10_float_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; y += 1) { |
const float *src = src_row; |
uint8_t *dst = dst_row; |
for(x = 0; x < width; x += 1) { |
uint32_t value = float3_to_r11g11b10f(src); |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*(uint32_t *)dst = value; |
src += 4; |
dst += 4; |
} |
dst_row += dst_stride; |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_r11g11b10_float_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j) |
{ |
uint32_t value = *(const uint32_t *)src; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
r11g11b10f_to_float3(value, dst); |
dst[3] = 1; /* a */ |
} |
void |
util_format_r11g11b10_float_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
float p[3]; |
for(y = 0; y < height; y += 1) { |
uint8_t *dst = dst_row; |
const uint8_t *src = src_row; |
for(x = 0; x < width; x += 1) { |
uint32_t value = *(const uint32_t *)src; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
r11g11b10f_to_float3(value, p); |
dst[0] = float_to_ubyte(p[0]); /* r */ |
dst[1] = float_to_ubyte(p[1]); /* g */ |
dst[2] = float_to_ubyte(p[2]); /* b */ |
dst[3] = 255; /* a */ |
src += 4; |
dst += 4; |
} |
src_row += src_stride; |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_r11g11b10_float_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
float p[3]; |
for(y = 0; y < height; y += 1) { |
const uint8_t *src = src_row; |
uint8_t *dst = dst_row; |
for(x = 0; x < width; x += 1) { |
uint32_t value; |
p[0] = ubyte_to_float(src[0]); |
p[1] = ubyte_to_float(src[1]); |
p[2] = ubyte_to_float(src[2]); |
value = float3_to_r11g11b10f(p); |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*(uint32_t *)dst = value; |
src += 4; |
dst += 4; |
} |
dst_row += dst_stride; |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_r1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
} |
void |
util_format_r1_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
} |
void |
util_format_r1_unorm_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j) |
{ |
} |
void |
util_format_r1_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
} |
void |
util_format_r1_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
} |
/* |
* PIPE_FORMAT_R8G8Bx_SNORM |
* |
* A.k.a. D3DFMT_CxV8U8 |
*/ |
static uint8_t |
r8g8bx_derive(int16_t r, int16_t g) |
{ |
/* Derive blue from red and green components. |
* Apparently, we must always use integers to perform calculations, |
* otherwise the results won't match D3D's CxV8U8 definition. |
*/ |
return (uint8_t)sqrtf(0x7f * 0x7f - r * r - g * g) * 0xff / 0x7f; |
} |
void |
util_format_r8g8bx_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; y += 1) { |
float *dst = dst_row; |
const uint16_t *src = (const uint16_t *)src_row; |
for(x = 0; x < width; x += 1) { |
uint16_t value = *src++; |
int16_t r, g; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap16(value); |
#endif |
r = ((int16_t)(value << 8)) >> 8; |
g = ((int16_t)(value << 0)) >> 8; |
dst[0] = (float)(r * (1.0f/0x7f)); /* r */ |
dst[1] = (float)(g * (1.0f/0x7f)); /* g */ |
dst[2] = r8g8bx_derive(r, g) * (1.0f/0xff); /* b */ |
dst[3] = 1.0f; /* a */ |
dst += 4; |
} |
src_row += src_stride; |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_r8g8bx_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; y += 1) { |
uint8_t *dst = dst_row; |
const uint16_t *src = (const uint16_t *)src_row; |
for(x = 0; x < width; x += 1) { |
uint16_t value = *src++; |
int16_t r, g; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap16(value); |
#endif |
r = ((int16_t)(value << 8)) >> 8; |
g = ((int16_t)(value << 0)) >> 8; |
dst[0] = (uint8_t)(((uint16_t)MAX2(r, 0)) * 0xff / 0x7f); /* r */ |
dst[1] = (uint8_t)(((uint16_t)MAX2(g, 0)) * 0xff / 0x7f); /* g */ |
dst[2] = r8g8bx_derive(r, g); /* b */ |
dst[3] = 255; /* a */ |
dst += 4; |
} |
src_row += src_stride; |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_r8g8bx_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; y += 1) { |
const float *src = src_row; |
uint16_t *dst = (uint16_t *)dst_row; |
for(x = 0; x < width; x += 1) { |
uint16_t value = 0; |
value |= (uint16_t)(((int8_t)(CLAMP(src[0], -1, 1) * 0x7f)) & 0xff) ; |
value |= (uint16_t)((((int8_t)(CLAMP(src[1], -1, 1) * 0x7f)) & 0xff) << 8) ; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap16(value); |
#endif |
*dst++ = value; |
src += 4; |
} |
dst_row += dst_stride; |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_r8g8bx_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; y += 1) { |
const uint8_t *src = src_row; |
uint16_t *dst = (uint16_t *)dst_row; |
for(x = 0; x < width; x += 1) { |
uint16_t value = 0; |
value |= src[0] >> 1; |
value |= (src[1] >> 1) << 8; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap16(value); |
#endif |
*dst++ = value; |
src += 4; |
} |
dst_row += dst_stride; |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_r8g8bx_snorm_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j) |
{ |
uint16_t value = *(const uint16_t *)src; |
int16_t r, g; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap16(value); |
#endif |
r = ((int16_t)(value << 8)) >> 8; |
g = ((int16_t)(value << 0)) >> 8; |
dst[0] = r * (1.0f/0x7f); /* r */ |
dst[1] = g * (1.0f/0x7f); /* g */ |
dst[2] = r8g8bx_derive(r, g) * (1.0f/0xff); /* b */ |
dst[3] = 1.0f; /* a */ |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_format_other.h |
---|
0,0 → 1,134 |
/************************************************************************** |
* |
* Copyright 2010 VMware, Inc. |
* 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 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 |
* THE COPYRIGHT HOLDERS, 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. |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
**************************************************************************/ |
#ifndef U_FORMAT_OTHER_H_ |
#define U_FORMAT_OTHER_H_ |
#include "pipe/p_compiler.h" |
void |
util_format_r9g9b9e5_float_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_r9g9b9e5_float_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_r9g9b9e5_float_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j); |
void |
util_format_r9g9b9e5_float_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_r9g9b9e5_float_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_r11g11b10_float_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_r11g11b10_float_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_r11g11b10_float_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j); |
void |
util_format_r11g11b10_float_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_r11g11b10_float_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_r1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_r1_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_r1_unorm_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j); |
void |
util_format_r1_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_r1_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_r8g8bx_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_r8g8bx_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_r8g8bx_snorm_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j); |
void |
util_format_r8g8bx_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_r8g8bx_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
#endif /* U_FORMAT_OTHER_H_ */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_format_pack.py |
---|
0,0 → 1,700 |
#!/usr/bin/env python |
''' |
/************************************************************************** |
* |
* Copyright 2009-2010 VMware, Inc. |
* 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 VMWARE 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. |
* |
**************************************************************************/ |
/** |
* @file |
* Pixel format packing and unpacking functions. |
* |
* @author Jose Fonseca <jfonseca@vmware.com> |
*/ |
''' |
from u_format_parse import * |
def generate_format_type(format): |
'''Generate a structure that describes the format.''' |
assert format.layout == PLAIN |
print 'union util_format_%s {' % format.short_name() |
if format.block_size() in (8, 16, 32, 64): |
print ' uint%u_t value;' % (format.block_size(),) |
use_bitfields = False |
for channel in format.channels: |
if channel.size % 8 or not is_pot(channel.size): |
use_bitfields = True |
print ' struct {' |
for channel in format.channels: |
if use_bitfields: |
if channel.type == VOID: |
if channel.size: |
print ' unsigned %s:%u;' % (channel.name, channel.size) |
elif channel.type == UNSIGNED: |
print ' unsigned %s:%u;' % (channel.name, channel.size) |
elif channel.type in (SIGNED, FIXED): |
print ' int %s:%u;' % (channel.name, channel.size) |
elif channel.type == FLOAT: |
if channel.size == 64: |
print ' double %s;' % (channel.name) |
elif channel.size == 32: |
print ' float %s;' % (channel.name) |
else: |
print ' unsigned %s:%u;' % (channel.name, channel.size) |
else: |
assert 0 |
else: |
assert channel.size % 8 == 0 and is_pot(channel.size) |
if channel.type == VOID: |
if channel.size: |
print ' uint%u_t %s;' % (channel.size, channel.name) |
elif channel.type == UNSIGNED: |
print ' uint%u_t %s;' % (channel.size, channel.name) |
elif channel.type in (SIGNED, FIXED): |
print ' int%u_t %s;' % (channel.size, channel.name) |
elif channel.type == FLOAT: |
if channel.size == 64: |
print ' double %s;' % (channel.name) |
elif channel.size == 32: |
print ' float %s;' % (channel.name) |
elif channel.size == 16: |
print ' uint16_t %s;' % (channel.name) |
else: |
assert 0 |
else: |
assert 0 |
print ' } chan;' |
print '};' |
def is_format_supported(format): |
'''Determines whether we actually have the plumbing necessary to generate the |
to read/write to/from this format.''' |
# FIXME: Ideally we would support any format combination here. |
if format.layout != PLAIN: |
return False |
for i in range(4): |
channel = format.channels[i] |
if channel.type not in (VOID, UNSIGNED, SIGNED, FLOAT, FIXED): |
return False |
if channel.type == FLOAT and channel.size not in (16, 32, 64): |
return False |
return True |
def is_format_pure_unsigned(format): |
for i in range(4): |
channel = format.channels[i] |
if channel.type not in (VOID, UNSIGNED): |
return False |
if channel.type == UNSIGNED and channel.pure == False: |
return False |
return True |
def is_format_pure_signed(format): |
for i in range(4): |
channel = format.channels[i] |
if channel.type not in (VOID, SIGNED): |
return False |
if channel.type == SIGNED and channel.pure == False: |
return False |
return True |
def native_type(format): |
'''Get the native appropriate for a format.''' |
if format.name == 'PIPE_FORMAT_R11G11B10_FLOAT': |
return 'uint32_t' |
if format.name == 'PIPE_FORMAT_R9G9B9E5_FLOAT': |
return 'uint32_t' |
if format.layout == PLAIN: |
if not format.is_array(): |
# For arithmetic pixel formats return the integer type that matches the whole pixel |
return 'uint%u_t' % format.block_size() |
else: |
# For array pixel formats return the integer type that matches the color channel |
channel = format.channels[0] |
if channel.type in (UNSIGNED, VOID): |
return 'uint%u_t' % channel.size |
elif channel.type in (SIGNED, FIXED): |
return 'int%u_t' % channel.size |
elif channel.type == FLOAT: |
if channel.size == 16: |
return 'uint16_t' |
elif channel.size == 32: |
return 'float' |
elif channel.size == 64: |
return 'double' |
else: |
assert False |
else: |
assert False |
else: |
assert False |
def intermediate_native_type(bits, sign): |
'''Find a native type adequate to hold intermediate results of the request bit size.''' |
bytes = 4 # don't use anything smaller than 32bits |
while bytes * 8 < bits: |
bytes *= 2 |
bits = bytes*8 |
if sign: |
return 'int%u_t' % bits |
else: |
return 'uint%u_t' % bits |
def get_one_shift(type): |
'''Get the number of the bit that matches unity for this type.''' |
if type.type == 'FLOAT': |
assert False |
if not type.norm: |
return 0 |
if type.type == UNSIGNED: |
return type.size |
if type.type == SIGNED: |
return type.size - 1 |
if type.type == FIXED: |
return type.size / 2 |
assert False |
def value_to_native(type, value): |
'''Get the value of unity for this type.''' |
if type.type == FLOAT: |
return value |
if type.type == FIXED: |
return int(value * (1 << (type.size/2))) |
if not type.norm: |
return int(value) |
if type.type == UNSIGNED: |
return int(value * ((1 << type.size) - 1)) |
if type.type == SIGNED: |
return int(value * ((1 << (type.size - 1)) - 1)) |
assert False |
def native_to_constant(type, value): |
'''Get the value of unity for this type.''' |
if type.type == FLOAT: |
if type.size <= 32: |
return "%ff" % value |
else: |
return "%ff" % value |
else: |
return str(int(value)) |
def get_one(type): |
'''Get the value of unity for this type.''' |
return value_to_native(type, 1) |
def clamp_expr(src_channel, dst_channel, dst_native_type, value): |
'''Generate the expression to clamp the value in the source type to the |
destination type range.''' |
if src_channel == dst_channel: |
return value |
src_min = src_channel.min() |
src_max = src_channel.max() |
dst_min = dst_channel.min() |
dst_max = dst_channel.max() |
# Translate the destination range to the src native value |
dst_min_native = value_to_native(src_channel, dst_min) |
dst_max_native = value_to_native(src_channel, dst_max) |
if src_min < dst_min and src_max > dst_max: |
return 'CLAMP(%s, %s, %s)' % (value, dst_min_native, dst_max_native) |
if src_max > dst_max: |
return 'MIN2(%s, %s)' % (value, dst_max_native) |
if src_min < dst_min: |
return 'MAX2(%s, %s)' % (value, dst_min_native) |
return value |
def conversion_expr(src_channel, |
dst_channel, dst_native_type, |
value, |
clamp=True, |
src_colorspace = RGB, |
dst_colorspace = RGB): |
'''Generate the expression to convert a value between two types.''' |
if src_colorspace != dst_colorspace: |
if src_colorspace == SRGB: |
assert src_channel.type == UNSIGNED |
assert src_channel.norm |
assert src_channel.size == 8 |
assert dst_colorspace == RGB |
if dst_channel.type == FLOAT: |
return 'util_format_srgb_8unorm_to_linear_float(%s)' % value |
else: |
assert dst_channel.type == UNSIGNED |
assert dst_channel.norm |
assert dst_channel.size == 8 |
return 'util_format_srgb_to_linear_8unorm(%s)' % value |
elif dst_colorspace == SRGB: |
assert dst_channel.type == UNSIGNED |
assert dst_channel.norm |
assert dst_channel.size == 8 |
assert src_colorspace == RGB |
if src_channel.type == FLOAT: |
return 'util_format_linear_float_to_srgb_8unorm(%s)' % value |
else: |
assert src_channel.type == UNSIGNED |
assert src_channel.norm |
assert src_channel.size == 8 |
return 'util_format_linear_to_srgb_8unorm(%s)' % value |
elif src_colorspace == ZS: |
pass |
elif dst_colorspace == ZS: |
pass |
else: |
assert 0 |
if src_channel == dst_channel: |
return value |
src_type = src_channel.type |
src_size = src_channel.size |
src_norm = src_channel.norm |
src_pure = src_channel.pure |
# Promote half to float |
if src_type == FLOAT and src_size == 16: |
value = 'util_half_to_float(%s)' % value |
src_size = 32 |
# Special case for float <-> ubytes for more accurate results |
# Done before clamping since these functions already take care of that |
if src_type == UNSIGNED and src_norm and src_size == 8 and dst_channel.type == FLOAT and dst_channel.size == 32: |
return 'ubyte_to_float(%s)' % value |
if src_type == FLOAT and src_size == 32 and dst_channel.type == UNSIGNED and dst_channel.norm and dst_channel.size == 8: |
return 'float_to_ubyte(%s)' % value |
if clamp: |
if dst_channel.type != FLOAT or src_type != FLOAT: |
value = clamp_expr(src_channel, dst_channel, dst_native_type, value) |
if src_type in (SIGNED, UNSIGNED) and dst_channel.type in (SIGNED, UNSIGNED): |
if not src_norm and not dst_channel.norm: |
# neither is normalized -- just cast |
return '(%s)%s' % (dst_native_type, value) |
src_one = get_one(src_channel) |
dst_one = get_one(dst_channel) |
if src_one > dst_one and src_norm and dst_channel.norm: |
# We can just bitshift |
src_shift = get_one_shift(src_channel) |
dst_shift = get_one_shift(dst_channel) |
value = '(%s >> %s)' % (value, src_shift - dst_shift) |
else: |
# We need to rescale using an intermediate type big enough to hold the multiplication of both |
tmp_native_type = intermediate_native_type(src_size + dst_channel.size, src_channel.sign and dst_channel.sign) |
value = '((%s)%s)' % (tmp_native_type, value) |
value = '(%s * 0x%x / 0x%x)' % (value, dst_one, src_one) |
value = '(%s)%s' % (dst_native_type, value) |
return value |
# Promote to either float or double |
if src_type != FLOAT: |
if src_norm or src_type == FIXED: |
one = get_one(src_channel) |
if src_size <= 23: |
value = '(%s * (1.0f/0x%x))' % (value, one) |
if dst_channel.size <= 32: |
value = '(float)%s' % value |
src_size = 32 |
else: |
# bigger than single precision mantissa, use double |
value = '(%s * (1.0/0x%x))' % (value, one) |
src_size = 64 |
src_norm = False |
else: |
if src_size <= 23 or dst_channel.size <= 32: |
value = '(float)%s' % value |
src_size = 32 |
else: |
# bigger than single precision mantissa, use double |
value = '(double)%s' % value |
src_size = 64 |
src_type = FLOAT |
# Convert double or float to non-float |
if dst_channel.type != FLOAT: |
if dst_channel.norm or dst_channel.type == FIXED: |
dst_one = get_one(dst_channel) |
if dst_channel.size <= 23: |
value = 'util_iround(%s * 0x%x)' % (value, dst_one) |
else: |
# bigger than single precision mantissa, use double |
value = '(%s * (double)0x%x)' % (value, dst_one) |
value = '(%s)%s' % (dst_native_type, value) |
else: |
# Cast double to float when converting to either half or float |
if dst_channel.size <= 32 and src_size > 32: |
value = '(float)%s' % value |
src_size = 32 |
if dst_channel.size == 16: |
value = 'util_float_to_half(%s)' % value |
elif dst_channel.size == 64 and src_size < 64: |
value = '(double)%s' % value |
return value |
def generate_unpack_kernel(format, dst_channel, dst_native_type): |
if not is_format_supported(format): |
return |
assert format.layout == PLAIN |
src_native_type = native_type(format) |
if format.is_bitmask(): |
depth = format.block_size() |
print ' uint%u_t value = *(const uint%u_t *)src;' % (depth, depth) |
# Declare the intermediate variables |
for i in range(format.nr_channels()): |
src_channel = format.channels[i] |
if src_channel.type == UNSIGNED: |
print ' uint%u_t %s;' % (depth, src_channel.name) |
elif src_channel.type == SIGNED: |
print ' int%u_t %s;' % (depth, src_channel.name) |
# Compute the intermediate unshifted values |
for i in range(format.nr_channels()): |
src_channel = format.channels[i] |
value = 'value' |
shift = src_channel.shift |
if src_channel.type == UNSIGNED: |
if shift: |
value = '%s >> %u' % (value, shift) |
if shift + src_channel.size < depth: |
value = '(%s) & 0x%x' % (value, (1 << src_channel.size) - 1) |
elif src_channel.type == SIGNED: |
if shift + src_channel.size < depth: |
# Align the sign bit |
lshift = depth - (shift + src_channel.size) |
value = '%s << %u' % (value, lshift) |
# Cast to signed |
value = '(int%u_t)(%s) ' % (depth, value) |
if src_channel.size < depth: |
# Align the LSB bit |
rshift = depth - src_channel.size |
value = '(%s) >> %u' % (value, rshift) |
else: |
value = None |
if value is not None: |
print ' %s = %s;' % (src_channel.name, value) |
# Convert, swizzle, and store final values |
for i in range(4): |
swizzle = format.swizzles[i] |
if swizzle < 4: |
src_channel = format.channels[swizzle] |
src_colorspace = format.colorspace |
if src_colorspace == SRGB and i == 3: |
# Alpha channel is linear |
src_colorspace = RGB |
value = src_channel.name |
value = conversion_expr(src_channel, |
dst_channel, dst_native_type, |
value, |
src_colorspace = src_colorspace) |
elif swizzle == SWIZZLE_0: |
value = '0' |
elif swizzle == SWIZZLE_1: |
value = get_one(dst_channel) |
elif swizzle == SWIZZLE_NONE: |
value = '0' |
else: |
assert False |
print ' dst[%u] = %s; /* %s */' % (i, value, 'rgba'[i]) |
else: |
print ' union util_format_%s pixel;' % format.short_name() |
print ' memcpy(&pixel, src, sizeof pixel);' |
for i in range(4): |
swizzle = format.swizzles[i] |
if swizzle < 4: |
src_channel = format.channels[swizzle] |
src_colorspace = format.colorspace |
if src_colorspace == SRGB and i == 3: |
# Alpha channel is linear |
src_colorspace = RGB |
value = 'pixel.chan.%s' % src_channel.name |
value = conversion_expr(src_channel, |
dst_channel, dst_native_type, |
value, |
src_colorspace = src_colorspace) |
elif swizzle == SWIZZLE_0: |
value = '0' |
elif swizzle == SWIZZLE_1: |
value = get_one(dst_channel) |
elif swizzle == SWIZZLE_NONE: |
value = '0' |
else: |
assert False |
print ' dst[%u] = %s; /* %s */' % (i, value, 'rgba'[i]) |
def generate_pack_kernel(format, src_channel, src_native_type): |
if not is_format_supported(format): |
return |
dst_native_type = native_type(format) |
assert format.layout == PLAIN |
inv_swizzle = format.inv_swizzles() |
if format.is_bitmask(): |
depth = format.block_size() |
print ' uint%u_t value = 0;' % depth |
for i in range(4): |
dst_channel = format.channels[i] |
shift = dst_channel.shift |
if inv_swizzle[i] is not None: |
value ='src[%u]' % inv_swizzle[i] |
dst_colorspace = format.colorspace |
if dst_colorspace == SRGB and inv_swizzle[i] == 3: |
# Alpha channel is linear |
dst_colorspace = RGB |
value = conversion_expr(src_channel, |
dst_channel, dst_native_type, |
value, |
dst_colorspace = dst_colorspace) |
if dst_channel.type in (UNSIGNED, SIGNED): |
if shift + dst_channel.size < depth: |
value = '(%s) & 0x%x' % (value, (1 << dst_channel.size) - 1) |
if shift: |
value = '(%s) << %u' % (value, shift) |
if dst_channel.type == SIGNED: |
# Cast to unsigned |
value = '(uint%u_t)(%s) ' % (depth, value) |
else: |
value = None |
if value is not None: |
print ' value |= %s;' % (value) |
print ' *(uint%u_t *)dst = value;' % depth |
else: |
print ' union util_format_%s pixel;' % format.short_name() |
for i in range(4): |
dst_channel = format.channels[i] |
width = dst_channel.size |
if inv_swizzle[i] is None: |
continue |
dst_colorspace = format.colorspace |
if dst_colorspace == SRGB and inv_swizzle[i] == 3: |
# Alpha channel is linear |
dst_colorspace = RGB |
value ='src[%u]' % inv_swizzle[i] |
value = conversion_expr(src_channel, |
dst_channel, dst_native_type, |
value, |
dst_colorspace = dst_colorspace) |
print ' pixel.chan.%s = %s;' % (dst_channel.name, value) |
print ' memcpy(dst, &pixel, sizeof pixel);' |
def generate_format_unpack(format, dst_channel, dst_native_type, dst_suffix): |
'''Generate the function to unpack pixels from a particular format''' |
name = format.short_name() |
print 'static INLINE void' |
print 'util_format_%s_unpack_%s(%s *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height)' % (name, dst_suffix, dst_native_type) |
print '{' |
if is_format_supported(format): |
print ' unsigned x, y;' |
print ' for(y = 0; y < height; y += %u) {' % (format.block_height,) |
print ' %s *dst = dst_row;' % (dst_native_type) |
print ' const uint8_t *src = src_row;' |
print ' for(x = 0; x < width; x += %u) {' % (format.block_width,) |
generate_unpack_kernel(format, dst_channel, dst_native_type) |
print ' src += %u;' % (format.block_size() / 8,) |
print ' dst += 4;' |
print ' }' |
print ' src_row += src_stride;' |
print ' dst_row += dst_stride/sizeof(*dst_row);' |
print ' }' |
print '}' |
def generate_format_pack(format, src_channel, src_native_type, src_suffix): |
'''Generate the function to pack pixels to a particular format''' |
name = format.short_name() |
print 'static INLINE void' |
print 'util_format_%s_pack_%s(uint8_t *dst_row, unsigned dst_stride, const %s *src_row, unsigned src_stride, unsigned width, unsigned height)' % (name, src_suffix, src_native_type) |
print '{' |
if is_format_supported(format): |
print ' unsigned x, y;' |
print ' for(y = 0; y < height; y += %u) {' % (format.block_height,) |
print ' const %s *src = src_row;' % (src_native_type) |
print ' uint8_t *dst = dst_row;' |
print ' for(x = 0; x < width; x += %u) {' % (format.block_width,) |
generate_pack_kernel(format, src_channel, src_native_type) |
print ' src += 4;' |
print ' dst += %u;' % (format.block_size() / 8,) |
print ' }' |
print ' dst_row += dst_stride;' |
print ' src_row += src_stride/sizeof(*src_row);' |
print ' }' |
print '}' |
def generate_format_fetch(format, dst_channel, dst_native_type, dst_suffix): |
'''Generate the function to unpack pixels from a particular format''' |
name = format.short_name() |
print 'static INLINE void' |
print 'util_format_%s_fetch_%s(%s *dst, const uint8_t *src, unsigned i, unsigned j)' % (name, dst_suffix, dst_native_type) |
print '{' |
if is_format_supported(format): |
generate_unpack_kernel(format, dst_channel, dst_native_type) |
print '}' |
def is_format_hand_written(format): |
return format.layout in ('s3tc', 'rgtc', 'etc', 'subsampled', 'other') or format.colorspace == ZS |
def generate(formats): |
print '#include "pipe/p_compiler.h"' |
print '#include "u_math.h"' |
print '#include "u_half.h"' |
print '#include "u_format.h"' |
print '#include "u_format_other.h"' |
print '#include "u_format_srgb.h"' |
print '#include "u_format_yuv.h"' |
print '#include "u_format_zs.h"' |
for format in formats: |
if not is_format_hand_written(format): |
if is_format_supported(format): |
generate_format_type(format) |
if is_format_pure_unsigned(format): |
native_type = 'unsigned' |
suffix = 'unsigned' |
channel = Channel(UNSIGNED, False, True, 32) |
generate_format_unpack(format, channel, native_type, suffix) |
generate_format_pack(format, channel, native_type, suffix) |
generate_format_fetch(format, channel, native_type, suffix) |
channel = Channel(SIGNED, False, True, 32) |
native_type = 'int' |
suffix = 'signed' |
generate_format_unpack(format, channel, native_type, suffix) |
generate_format_pack(format, channel, native_type, suffix) |
elif is_format_pure_signed(format): |
native_type = 'int' |
suffix = 'signed' |
channel = Channel(SIGNED, False, True, 32) |
generate_format_unpack(format, channel, native_type, suffix) |
generate_format_pack(format, channel, native_type, suffix) |
generate_format_fetch(format, channel, native_type, suffix) |
native_type = 'unsigned' |
suffix = 'unsigned' |
channel = Channel(UNSIGNED, False, True, 32) |
generate_format_unpack(format, channel, native_type, suffix) |
generate_format_pack(format, channel, native_type, suffix) |
else: |
channel = Channel(FLOAT, False, False, 32) |
native_type = 'float' |
suffix = 'rgba_float' |
generate_format_unpack(format, channel, native_type, suffix) |
generate_format_pack(format, channel, native_type, suffix) |
generate_format_fetch(format, channel, native_type, suffix) |
channel = Channel(UNSIGNED, True, False, 8) |
native_type = 'uint8_t' |
suffix = 'rgba_8unorm' |
generate_format_unpack(format, channel, native_type, suffix) |
generate_format_pack(format, channel, native_type, suffix) |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_format_parse.py |
---|
0,0 → 1,323 |
#!/usr/bin/env python |
''' |
/************************************************************************** |
* |
* Copyright 2009 VMware, Inc. |
* 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 VMWARE 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. |
* |
**************************************************************************/ |
''' |
import sys |
VOID, UNSIGNED, SIGNED, FIXED, FLOAT = range(5) |
SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W, SWIZZLE_0, SWIZZLE_1, SWIZZLE_NONE, = range(7) |
PLAIN = 'plain' |
RGB = 'rgb' |
SRGB = 'srgb' |
YUV = 'yuv' |
ZS = 'zs' |
# Not cross-compiler friendly |
is_big_endian = sys.byteorder == 'big' |
def is_pot(x): |
return (x & (x - 1)) == 0 |
VERY_LARGE = 99999999999999999999999 |
class Channel: |
'''Describe the channel of a color channel.''' |
def __init__(self, type, norm, pure, size, name = ''): |
self.type = type |
self.norm = norm |
self.pure = pure |
self.size = size |
self.sign = type in (SIGNED, FIXED, FLOAT) |
self.name = name |
def __str__(self): |
s = str(self.type) |
if self.norm: |
s += 'n' |
if self.pure: |
s += 'p' |
s += str(self.size) |
return s |
def __eq__(self, other): |
return self.type == other.type and self.norm == other.norm and self.pure == other.pure and self.size == other.size |
def max(self): |
'''Maximum representable number.''' |
if self.type == FLOAT: |
return VERY_LARGE |
if self.type == FIXED: |
return (1 << (self.size/2)) - 1 |
if self.norm: |
return 1 |
if self.type == UNSIGNED: |
return (1 << self.size) - 1 |
if self.type == SIGNED: |
return (1 << (self.size - 1)) - 1 |
assert False |
def min(self): |
'''Minimum representable number.''' |
if self.type == FLOAT: |
return -VERY_LARGE |
if self.type == FIXED: |
return -(1 << (self.size/2)) |
if self.type == UNSIGNED: |
return 0 |
if self.norm: |
return -1 |
if self.type == SIGNED: |
return -(1 << (self.size - 1)) |
assert False |
class Format: |
'''Describe a pixel format.''' |
def __init__(self, name, layout, block_width, block_height, channels, swizzles, colorspace): |
self.name = name |
self.layout = layout |
self.block_width = block_width |
self.block_height = block_height |
self.channels = channels |
self.swizzles = swizzles |
self.name = name |
self.colorspace = colorspace |
def __str__(self): |
return self.name |
def short_name(self): |
'''Make up a short norm for a format, suitable to be used as suffix in |
function names.''' |
name = self.name |
if name.startswith('PIPE_FORMAT_'): |
name = name[len('PIPE_FORMAT_'):] |
name = name.lower() |
return name |
def block_size(self): |
size = 0 |
for channel in self.channels: |
size += channel.size |
return size |
def nr_channels(self): |
nr_channels = 0 |
for channel in self.channels: |
if channel.size: |
nr_channels += 1 |
return nr_channels |
def is_array(self): |
if self.layout != PLAIN: |
return False |
ref_channel = self.channels[0] |
if ref_channel.type == VOID: |
ref_channel = self.channels[1] |
for channel in self.channels: |
if channel.size and (channel.size != ref_channel.size or channel.size % 8): |
return False |
if channel.type != VOID: |
if channel.type != ref_channel.type: |
return False |
if channel.norm != ref_channel.norm: |
return False |
if channel.pure != ref_channel.pure: |
return False |
return True |
def is_mixed(self): |
if self.layout != PLAIN: |
return False |
ref_channel = self.channels[0] |
if ref_channel.type == VOID: |
ref_channel = self.channels[1] |
for channel in self.channels[1:]: |
if channel.type != VOID: |
if channel.type != ref_channel.type: |
return True |
if channel.norm != ref_channel.norm: |
return True |
if channel.pure != ref_channel.pure: |
return True |
return False |
def is_pot(self): |
return is_pot(self.block_size()) |
def is_int(self): |
if self.layout != PLAIN: |
return False |
for channel in self.channels: |
if channel.type not in (VOID, UNSIGNED, SIGNED): |
return False |
return True |
def is_float(self): |
if self.layout != PLAIN: |
return False |
for channel in self.channels: |
if channel.type not in (VOID, FLOAT): |
return False |
return True |
def is_bitmask(self): |
if self.layout != PLAIN: |
return False |
if self.block_size() not in (8, 16, 32): |
return False |
for channel in self.channels: |
if channel.type not in (VOID, UNSIGNED, SIGNED): |
return False |
return True |
def inv_swizzles(self): |
'''Return an array[4] of inverse swizzle terms''' |
'''Only pick the first matching value to avoid l8 getting blue and i8 getting alpha''' |
inv_swizzle = [None]*4 |
for i in range(4): |
swizzle = self.swizzles[i] |
if swizzle < 4 and inv_swizzle[swizzle] == None: |
inv_swizzle[swizzle] = i |
return inv_swizzle |
def stride(self): |
return self.block_size()/8 |
_type_parse_map = { |
'': VOID, |
'x': VOID, |
'u': UNSIGNED, |
's': SIGNED, |
'h': FIXED, |
'f': FLOAT, |
} |
_swizzle_parse_map = { |
'x': SWIZZLE_X, |
'y': SWIZZLE_Y, |
'z': SWIZZLE_Z, |
'w': SWIZZLE_W, |
'0': SWIZZLE_0, |
'1': SWIZZLE_1, |
'_': SWIZZLE_NONE, |
} |
def parse(filename): |
'''Parse the format descrition in CSV format in terms of the |
Channel and Format classes above.''' |
stream = open(filename) |
formats = [] |
for line in stream: |
try: |
comment = line.index('#') |
except ValueError: |
pass |
else: |
line = line[:comment] |
line = line.strip() |
if not line: |
continue |
fields = [field.strip() for field in line.split(',')] |
name = fields[0] |
layout = fields[1] |
block_width, block_height = map(int, fields[2:4]) |
swizzles = [_swizzle_parse_map[swizzle] for swizzle in fields[8]] |
colorspace = fields[9] |
if layout == PLAIN: |
names = ['']*4 |
if colorspace in (RGB, SRGB): |
for i in range(4): |
swizzle = swizzles[i] |
if swizzle < 4: |
names[swizzle] += 'rgba'[i] |
elif colorspace == ZS: |
for i in range(4): |
swizzle = swizzles[i] |
if swizzle < 4: |
names[swizzle] += 'zs'[i] |
else: |
assert False |
for i in range(4): |
if names[i] == '': |
names[i] = 'x' |
else: |
names = ['x', 'y', 'z', 'w'] |
channels = [] |
for i in range(0, 4): |
field = fields[4 + i] |
if field: |
type = _type_parse_map[field[0]] |
if field[1] == 'n': |
norm = True |
pure = False |
size = int(field[2:]) |
elif field[1] == 'p': |
pure = True |
norm = False |
size = int(field[2:]) |
else: |
norm = False |
pure = False |
size = int(field[1:]) |
else: |
type = VOID |
norm = False |
pure = False |
size = 0 |
channel = Channel(type, norm, pure, size, names[i]) |
channels.append(channel) |
shift = 0 |
for channel in channels[3::-1] if is_big_endian else channels: |
channel.shift = shift |
shift += channel.size |
format = Format(name, layout, block_width, block_height, channels, swizzles, colorspace) |
formats.append(format) |
return formats |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_format_r11g11b10f.h |
---|
0,0 → 1,232 |
/* |
* Copyright (C) 2011 Marek Olšák <maraeo@gmail.com> |
* |
* 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, sublicense, |
* 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 NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS 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. |
*/ |
/* Based on code from The OpenGL Programming Guide / 7th Edition, Appendix J. |
* Available here: http://www.opengl-redbook.com/appendices/ |
* The algorithm in the book contains a bug though, which is fixed in the code |
* below. |
*/ |
#define UF11(e, m) ((e << 6) | (m)) |
#define UF11_EXPONENT_BIAS 15 |
#define UF11_EXPONENT_BITS 0x1F |
#define UF11_EXPONENT_SHIFT 6 |
#define UF11_MANTISSA_BITS 0x3F |
#define UF11_MANTISSA_SHIFT (23 - UF11_EXPONENT_SHIFT) |
#define UF11_MAX_EXPONENT (UF11_EXPONENT_BITS << UF11_EXPONENT_SHIFT) |
#define UF10(e, m) ((e << 5) | (m)) |
#define UF10_EXPONENT_BIAS 15 |
#define UF10_EXPONENT_BITS 0x1F |
#define UF10_EXPONENT_SHIFT 5 |
#define UF10_MANTISSA_BITS 0x1F |
#define UF10_MANTISSA_SHIFT (23 - UF10_EXPONENT_SHIFT) |
#define UF10_MAX_EXPONENT (UF10_EXPONENT_BITS << UF10_EXPONENT_SHIFT) |
#define F32_INFINITY 0x7f800000 |
static INLINE unsigned f32_to_uf11(float val) |
{ |
union { |
float f; |
uint32_t ui; |
} f32 = {val}; |
uint16_t uf11 = 0; |
/* Decode little-endian 32-bit floating-point value */ |
int sign = (f32.ui >> 16) & 0x8000; |
/* Map exponent to the range [-127,128] */ |
int exponent = ((f32.ui >> 23) & 0xff) - 127; |
int mantissa = f32.ui & 0x007fffff; |
if (exponent == 128) { /* Infinity or NaN */ |
/* From the GL_EXT_packed_float spec: |
* |
* "Additionally: negative infinity is converted to zero; positive |
* infinity is converted to positive infinity; and both positive and |
* negative NaN are converted to positive NaN." |
*/ |
uf11 = UF11_MAX_EXPONENT; |
if (mantissa) { |
uf11 |= 1; /* NaN */ |
} else { |
if (sign) |
uf11 = 0; /* 0.0 */ |
} |
} else if (sign) { |
return 0; |
} else if (val > 65024.0f) { |
/* From the GL_EXT_packed_float spec: |
* |
* "Likewise, finite positive values greater than 65024 (the maximum |
* finite representable unsigned 11-bit floating-point value) are |
* converted to 65024." |
*/ |
uf11 = UF11(30, 63); |
} |
else if (exponent > -15) { /* Representable value */ |
exponent += UF11_EXPONENT_BIAS; |
mantissa >>= UF11_MANTISSA_SHIFT; |
uf11 = exponent << UF11_EXPONENT_SHIFT | mantissa; |
} |
return uf11; |
} |
static INLINE float uf11_to_f32(uint16_t val) |
{ |
union { |
float f; |
uint32_t ui; |
} f32; |
int exponent = (val & 0x07c0) >> UF11_EXPONENT_SHIFT; |
int mantissa = (val & 0x003f); |
f32.f = 0.0; |
if (exponent == 0) { |
if (mantissa != 0) { |
const float scale = 1.0 / (1 << 20); |
f32.f = scale * mantissa; |
} |
} |
else if (exponent == 31) { |
f32.ui = F32_INFINITY | mantissa; |
} |
else { |
float scale, decimal; |
exponent -= 15; |
if (exponent < 0) { |
scale = 1.0f / (1 << -exponent); |
} |
else { |
scale = (float) (1 << exponent); |
} |
decimal = 1.0f + (float) mantissa / 64; |
f32.f = scale * decimal; |
} |
return f32.f; |
} |
static INLINE unsigned f32_to_uf10(float val) |
{ |
union { |
float f; |
uint32_t ui; |
} f32 = {val}; |
uint16_t uf10 = 0; |
/* Decode little-endian 32-bit floating-point value */ |
int sign = (f32.ui >> 16) & 0x8000; |
/* Map exponent to the range [-127,128] */ |
int exponent = ((f32.ui >> 23) & 0xff) - 127; |
int mantissa = f32.ui & 0x007fffff; |
if (exponent == 128) { |
/* From the GL_EXT_packed_float spec: |
* |
* "Additionally: negative infinity is converted to zero; positive |
* infinity is converted to positive infinity; and both positive and |
* negative NaN are converted to positive NaN." |
*/ |
uf10 = UF10_MAX_EXPONENT; |
if (mantissa) { |
uf10 |= 1; /* NaN */ |
} else { |
if (sign) |
uf10 = 0; /* 0.0 */ |
} |
} else if (sign) { |
return 0; |
} else if (val > 64512.0f) { /* Overflow - flush to Infinity */ |
/* From the GL_EXT_packed_float spec: |
* |
* "Likewise, finite positive values greater than 64512 (the maximum |
* finite representable unsigned 10-bit floating-point value) are |
* converted to 64512." |
*/ |
uf10 = UF10(30, 31); |
} |
else if (exponent > -15) { /* Representable value */ |
exponent += UF10_EXPONENT_BIAS; |
mantissa >>= UF10_MANTISSA_SHIFT; |
uf10 = exponent << UF10_EXPONENT_SHIFT | mantissa; |
} |
return uf10; |
} |
static INLINE float uf10_to_f32(uint16_t val) |
{ |
union { |
float f; |
uint32_t ui; |
} f32; |
int exponent = (val & 0x03e0) >> UF10_EXPONENT_SHIFT; |
int mantissa = (val & 0x001f); |
f32.f = 0.0; |
if (exponent == 0) { |
if (mantissa != 0) { |
const float scale = 1.0 / (1 << 20); |
f32.f = scale * mantissa; |
} |
} |
else if (exponent == 31) { |
f32.ui = F32_INFINITY | mantissa; |
} |
else { |
float scale, decimal; |
exponent -= 15; |
if (exponent < 0) { |
scale = 1.0f / (1 << -exponent); |
} |
else { |
scale = (float) (1 << exponent); |
} |
decimal = 1.0f + (float) mantissa / 32; |
f32.f = scale * decimal; |
} |
return f32.f; |
} |
static INLINE unsigned float3_to_r11g11b10f(const float rgb[3]) |
{ |
return ( f32_to_uf11(rgb[0]) & 0x7ff) | |
((f32_to_uf11(rgb[1]) & 0x7ff) << 11) | |
((f32_to_uf10(rgb[2]) & 0x3ff) << 22); |
} |
static INLINE void r11g11b10f_to_float3(unsigned rgb, float retval[3]) |
{ |
retval[0] = uf11_to_f32( rgb & 0x7ff); |
retval[1] = uf11_to_f32((rgb >> 11) & 0x7ff); |
retval[2] = uf10_to_f32((rgb >> 22) & 0x3ff); |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_format_rgb9e5.h |
---|
0,0 → 1,164 |
/* |
* Copyright (C) 2011 Marek Olšák <maraeo@gmail.com> |
* |
* 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, sublicense, |
* 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 NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS 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. |
*/ |
/* Copied from EXT_texture_shared_exponent and edited. */ |
#ifndef RGB9E5_H |
#define RGB9E5_H |
#include <math.h> |
#include <assert.h> |
#define RGB9E5_EXPONENT_BITS 5 |
#define RGB9E5_MANTISSA_BITS 9 |
#define RGB9E5_EXP_BIAS 15 |
#define RGB9E5_MAX_VALID_BIASED_EXP 31 |
#define MAX_RGB9E5_EXP (RGB9E5_MAX_VALID_BIASED_EXP - RGB9E5_EXP_BIAS) |
#define RGB9E5_MANTISSA_VALUES (1<<RGB9E5_MANTISSA_BITS) |
#define MAX_RGB9E5_MANTISSA (RGB9E5_MANTISSA_VALUES-1) |
#define MAX_RGB9E5 (((float)MAX_RGB9E5_MANTISSA)/RGB9E5_MANTISSA_VALUES * (1<<MAX_RGB9E5_EXP)) |
#define EPSILON_RGB9E5 ((1.0/RGB9E5_MANTISSA_VALUES) / (1<<RGB9E5_EXP_BIAS)) |
typedef union { |
unsigned int raw; |
float value; |
struct { |
#if defined(MESA_BIG_ENDIAN) || defined(PIPE_ARCH_BIG_ENDIAN) |
unsigned int negative:1; |
unsigned int biasedexponent:8; |
unsigned int mantissa:23; |
#else |
unsigned int mantissa:23; |
unsigned int biasedexponent:8; |
unsigned int negative:1; |
#endif |
} field; |
} float754; |
typedef union { |
unsigned int raw; |
struct { |
#if defined(MESA_BIG_ENDIAN) || defined(PIPE_ARCH_BIG_ENDIAN) |
unsigned int biasedexponent:RGB9E5_EXPONENT_BITS; |
unsigned int b:RGB9E5_MANTISSA_BITS; |
unsigned int g:RGB9E5_MANTISSA_BITS; |
unsigned int r:RGB9E5_MANTISSA_BITS; |
#else |
unsigned int r:RGB9E5_MANTISSA_BITS; |
unsigned int g:RGB9E5_MANTISSA_BITS; |
unsigned int b:RGB9E5_MANTISSA_BITS; |
unsigned int biasedexponent:RGB9E5_EXPONENT_BITS; |
#endif |
} field; |
} rgb9e5; |
static INLINE float rgb9e5_ClampRange(float x) |
{ |
if (x > 0.0) { |
if (x >= MAX_RGB9E5) { |
return MAX_RGB9E5; |
} else { |
return x; |
} |
} else { |
/* NaN gets here too since comparisons with NaN always fail! */ |
return 0.0; |
} |
} |
/* Ok, FloorLog2 is not correct for the denorm and zero values, but we |
are going to do a max of this value with the minimum rgb9e5 exponent |
that will hide these problem cases. */ |
static INLINE int rgb9e5_FloorLog2(float x) |
{ |
float754 f; |
f.value = x; |
return (f.field.biasedexponent - 127); |
} |
static INLINE unsigned float3_to_rgb9e5(const float rgb[3]) |
{ |
rgb9e5 retval; |
float maxrgb; |
int rm, gm, bm; |
float rc, gc, bc; |
int exp_shared, maxm; |
double denom; |
rc = rgb9e5_ClampRange(rgb[0]); |
gc = rgb9e5_ClampRange(rgb[1]); |
bc = rgb9e5_ClampRange(rgb[2]); |
maxrgb = MAX3(rc, gc, bc); |
exp_shared = MAX2(-RGB9E5_EXP_BIAS-1, rgb9e5_FloorLog2(maxrgb)) + 1 + RGB9E5_EXP_BIAS; |
assert(exp_shared <= RGB9E5_MAX_VALID_BIASED_EXP); |
assert(exp_shared >= 0); |
/* This pow function could be replaced by a table. */ |
denom = pow(2, exp_shared - RGB9E5_EXP_BIAS - RGB9E5_MANTISSA_BITS); |
maxm = (int) floor(maxrgb / denom + 0.5); |
if (maxm == MAX_RGB9E5_MANTISSA+1) { |
denom *= 2; |
exp_shared += 1; |
assert(exp_shared <= RGB9E5_MAX_VALID_BIASED_EXP); |
} else { |
assert(maxm <= MAX_RGB9E5_MANTISSA); |
} |
rm = (int) floor(rc / denom + 0.5); |
gm = (int) floor(gc / denom + 0.5); |
bm = (int) floor(bc / denom + 0.5); |
assert(rm <= MAX_RGB9E5_MANTISSA); |
assert(gm <= MAX_RGB9E5_MANTISSA); |
assert(bm <= MAX_RGB9E5_MANTISSA); |
assert(rm >= 0); |
assert(gm >= 0); |
assert(bm >= 0); |
retval.field.r = rm; |
retval.field.g = gm; |
retval.field.b = bm; |
retval.field.biasedexponent = exp_shared; |
return retval.raw; |
} |
static INLINE void rgb9e5_to_float3(unsigned rgb, float retval[3]) |
{ |
rgb9e5 v; |
int exponent; |
float scale; |
v.raw = rgb; |
exponent = v.field.biasedexponent - RGB9E5_EXP_BIAS - RGB9E5_MANTISSA_BITS; |
scale = (float) pow(2, exponent); |
retval[0] = v.field.r * scale; |
retval[1] = v.field.g * scale; |
retval[2] = v.field.b * scale; |
} |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_format_rgtc.c |
---|
0,0 → 1,474 |
/************************************************************************** |
* |
* Copyright (C) 2011 Red Hat Inc. |
* |
* 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, sublicense, |
* 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 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 NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS 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 <stdio.h> |
#include "u_math.h" |
#include "u_format.h" |
#include "u_format_rgtc.h" |
static void u_format_unsigned_encode_rgtc_ubyte(uint8_t *blkaddr, uint8_t srccolors[4][4], |
int numxpixels, int numypixels); |
static void u_format_unsigned_fetch_texel_rgtc(unsigned srcRowStride, const uint8_t *pixdata, |
unsigned i, unsigned j, uint8_t *value, unsigned comps); |
static void u_format_signed_encode_rgtc_ubyte(int8_t *blkaddr, int8_t srccolors[4][4], |
int numxpixels, int numypixels); |
static void u_format_signed_fetch_texel_rgtc(unsigned srcRowStride, const int8_t *pixdata, |
unsigned i, unsigned j, int8_t *value, unsigned comps); |
void |
util_format_rgtc1_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 1); |
dst[1] = 0; |
dst[2] = 0; |
dst[3] = 255; |
} |
void |
util_format_rgtc1_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
const unsigned bw = 4, bh = 4, comps = 4; |
unsigned x, y, i, j; |
unsigned block_size = 8; |
for(y = 0; y < height; y += bh) { |
const uint8_t *src = src_row; |
for(x = 0; x < width; x += bw) { |
for(j = 0; j < bh; ++j) { |
for(i = 0; i < bw; ++i) { |
uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*comps; |
u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 1); |
dst[1] = 0; |
dst[2] = 0; |
dst[3] = 255; |
} |
} |
src += block_size; |
} |
src_row += src_stride; |
} |
} |
void |
util_format_rgtc1_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, |
unsigned src_stride, unsigned width, unsigned height) |
{ |
const unsigned bw = 4, bh = 4, bytes_per_block = 8; |
unsigned x, y, i, j; |
for(y = 0; y < height; y += bh) { |
uint8_t *dst = dst_row; |
for(x = 0; x < width; x += bw) { |
uint8_t tmp[4][4]; /* [bh][bw][comps] */ |
for(j = 0; j < bh; ++j) { |
for(i = 0; i < bw; ++i) { |
tmp[j][i] = src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]; |
} |
} |
u_format_unsigned_encode_rgtc_ubyte(dst, tmp, 4, 4); |
dst += bytes_per_block; |
} |
dst_row += dst_stride / sizeof(*dst_row); |
} |
} |
void |
util_format_rgtc1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
unsigned x, y, i, j; |
int block_size = 8; |
for(y = 0; y < height; y += 4) { |
const uint8_t *src = src_row; |
for(x = 0; x < width; x += 4) { |
for(j = 0; j < 4; ++j) { |
for(i = 0; i < 4; ++i) { |
float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; |
uint8_t tmp_r; |
u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1); |
dst[0] = ubyte_to_float(tmp_r); |
dst[1] = 0.0; |
dst[2] = 0.0; |
dst[3] = 1.0; |
} |
} |
src += block_size; |
} |
src_row += src_stride; |
} |
} |
void |
util_format_rgtc1_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
const unsigned bw = 4, bh = 4, bytes_per_block = 8; |
unsigned x, y, i, j; |
for(y = 0; y < height; y += bh) { |
uint8_t *dst = dst_row; |
for(x = 0; x < width; x += bw) { |
uint8_t tmp[4][4]; /* [bh][bw][comps] */ |
for(j = 0; j < bh; ++j) { |
for(i = 0; i < bw; ++i) { |
tmp[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]); |
} |
} |
u_format_unsigned_encode_rgtc_ubyte(dst, tmp, 4, 4); |
dst += bytes_per_block; |
} |
dst_row += dst_stride / sizeof(*dst_row); |
} |
} |
void |
util_format_rgtc1_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
uint8_t tmp_r; |
u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1); |
dst[0] = ubyte_to_float(tmp_r); |
dst[1] = 0.0; |
dst[2] = 0.0; |
dst[3] = 1.0; |
} |
void |
util_format_rgtc1_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
fprintf(stderr,"%s\n", __func__); |
} |
void |
util_format_rgtc1_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
fprintf(stderr,"%s\n", __func__); |
} |
void |
util_format_rgtc1_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
fprintf(stderr,"%s\n", __func__); |
} |
void |
util_format_rgtc1_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
const unsigned bw = 4, bh = 4, bytes_per_block = 8; |
unsigned x, y, i, j; |
for(y = 0; y < height; y += bh) { |
int8_t *dst = (int8_t *)dst_row; |
for(x = 0; x < width; x += bw) { |
int8_t tmp[4][4]; /* [bh][bw][comps] */ |
for(j = 0; j < bh; ++j) { |
for(i = 0; i < bw; ++i) { |
tmp[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]); |
} |
} |
u_format_signed_encode_rgtc_ubyte(dst, tmp, 4, 4); |
dst += bytes_per_block; |
} |
dst_row += dst_stride / sizeof(*dst_row); |
} |
} |
void |
util_format_rgtc1_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
unsigned x, y, i, j; |
int block_size = 8; |
for(y = 0; y < height; y += 4) { |
const int8_t *src = (int8_t *)src_row; |
for(x = 0; x < width; x += 4) { |
for(j = 0; j < 4; ++j) { |
for(i = 0; i < 4; ++i) { |
float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; |
int8_t tmp_r; |
u_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 1); |
dst[0] = byte_to_float_tex(tmp_r); |
dst[1] = 0.0; |
dst[2] = 0.0; |
dst[3] = 1.0; |
} |
} |
src += block_size; |
} |
src_row += src_stride; |
} |
} |
void |
util_format_rgtc1_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
int8_t tmp_r; |
u_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 1); |
dst[0] = byte_to_float_tex(tmp_r); |
dst[1] = 0.0; |
dst[2] = 0.0; |
dst[3] = 1.0; |
} |
void |
util_format_rgtc2_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 2); |
u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, dst + 1, 2); |
dst[2] = 0; |
dst[3] = 255; |
} |
void |
util_format_rgtc2_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
const unsigned bw = 4, bh = 4, comps = 4; |
unsigned x, y, i, j; |
unsigned block_size = 16; |
for(y = 0; y < height; y += bh) { |
const uint8_t *src = src_row; |
for(x = 0; x < width; x += bw) { |
for(j = 0; j < bh; ++j) { |
for(i = 0; i < bw; ++i) { |
uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*comps; |
u_format_unsigned_fetch_texel_rgtc(0, src, i, j, dst, 2); |
u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, dst + 1, 2); |
dst[2] = 0; |
dst[3] = 255; |
} |
} |
src += block_size; |
} |
src_row += src_stride; |
} |
} |
void |
util_format_rgtc2_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
const unsigned bw = 4, bh = 4, bytes_per_block = 16; |
unsigned x, y, i, j; |
for(y = 0; y < height; y += bh) { |
uint8_t *dst = dst_row; |
for(x = 0; x < width; x += bw) { |
uint8_t tmp_r[4][4]; /* [bh][bw] */ |
uint8_t tmp_g[4][4]; /* [bh][bw] */ |
for(j = 0; j < bh; ++j) { |
for(i = 0; i < bw; ++i) { |
tmp_r[j][i] = src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]; |
tmp_g[j][i] = src_row[((y + j)*src_stride/sizeof(*src_row) + (x + i)*4) + 1]; |
} |
} |
u_format_unsigned_encode_rgtc_ubyte(dst, tmp_r, 4, 4); |
u_format_unsigned_encode_rgtc_ubyte(dst + 8, tmp_g, 4, 4); |
dst += bytes_per_block; |
} |
dst_row += dst_stride / sizeof(*dst_row); |
} |
} |
void |
util_format_rxtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height, unsigned chan2off) |
{ |
const unsigned bw = 4, bh = 4, bytes_per_block = 16; |
unsigned x, y, i, j; |
for(y = 0; y < height; y += bh) { |
uint8_t *dst = dst_row; |
for(x = 0; x < width; x += bw) { |
uint8_t tmp_r[4][4]; /* [bh][bw][comps] */ |
uint8_t tmp_g[4][4]; /* [bh][bw][comps] */ |
for(j = 0; j < bh; ++j) { |
for(i = 0; i < bw; ++i) { |
tmp_r[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]); |
tmp_g[j][i] = float_to_ubyte(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + chan2off]); |
} |
} |
u_format_unsigned_encode_rgtc_ubyte(dst, tmp_r, 4, 4); |
u_format_unsigned_encode_rgtc_ubyte(dst + 8, tmp_g, 4, 4); |
dst += bytes_per_block; |
} |
dst_row += dst_stride / sizeof(*dst_row); |
} |
} |
void |
util_format_rgtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_rxtc2_unorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 1); |
} |
void |
util_format_rgtc2_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
unsigned x, y, i, j; |
int block_size = 16; |
for(y = 0; y < height; y += 4) { |
const uint8_t *src = src_row; |
for(x = 0; x < width; x += 4) { |
for(j = 0; j < 4; ++j) { |
for(i = 0; i < 4; ++i) { |
float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; |
uint8_t tmp_r, tmp_g; |
u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2); |
u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2); |
dst[0] = ubyte_to_float(tmp_r); |
dst[1] = ubyte_to_float(tmp_g); |
dst[2] = 0.0; |
dst[3] = 1.0; |
} |
} |
src += block_size; |
} |
src_row += src_stride; |
} |
} |
void |
util_format_rgtc2_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
uint8_t tmp_r, tmp_g; |
u_format_unsigned_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2); |
u_format_unsigned_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2); |
dst[0] = ubyte_to_float(tmp_r); |
dst[1] = ubyte_to_float(tmp_g); |
dst[2] = 0.0; |
dst[3] = 1.0; |
} |
void |
util_format_rgtc2_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
fprintf(stderr,"%s\n", __func__); |
} |
void |
util_format_rgtc2_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
fprintf(stderr,"%s\n", __func__); |
} |
void |
util_format_rgtc2_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
fprintf(stderr,"%s\n", __func__); |
} |
void |
util_format_rgtc2_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
unsigned x, y, i, j; |
int block_size = 16; |
for(y = 0; y < height; y += 4) { |
const int8_t *src = (int8_t *)src_row; |
for(x = 0; x < width; x += 4) { |
for(j = 0; j < 4; ++j) { |
for(i = 0; i < 4; ++i) { |
float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; |
int8_t tmp_r, tmp_g; |
u_format_signed_fetch_texel_rgtc(0, src, i, j, &tmp_r, 2); |
u_format_signed_fetch_texel_rgtc(0, src + 8, i, j, &tmp_g, 2); |
dst[0] = byte_to_float_tex(tmp_r); |
dst[1] = byte_to_float_tex(tmp_g); |
dst[2] = 0.0; |
dst[3] = 1.0; |
} |
} |
src += block_size; |
} |
src_row += src_stride; |
} |
} |
void |
util_format_rxtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height, unsigned chan2off) |
{ |
const unsigned bw = 4, bh = 4, bytes_per_block = 16; |
unsigned x, y, i, j; |
for(y = 0; y < height; y += bh) { |
int8_t *dst = (int8_t *)dst_row; |
for(x = 0; x < width; x += bw) { |
int8_t tmp_r[4][4]; /* [bh][bw][comps] */ |
int8_t tmp_g[4][4]; /* [bh][bw][comps] */ |
for(j = 0; j < bh; ++j) { |
for(i = 0; i < bw; ++i) { |
tmp_r[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4]); |
tmp_g[j][i] = float_to_byte_tex(src_row[(y + j)*src_stride/sizeof(*src_row) + (x + i)*4 + chan2off]); |
} |
} |
u_format_signed_encode_rgtc_ubyte(dst, tmp_r, 4, 4); |
u_format_signed_encode_rgtc_ubyte(dst + 8, tmp_g, 4, 4); |
dst += bytes_per_block; |
} |
dst_row += dst_stride / sizeof(*dst_row); |
} |
} |
void |
util_format_rgtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_rxtc2_snorm_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, width, height, 1); |
} |
void |
util_format_rgtc2_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
int8_t tmp_r, tmp_g; |
u_format_signed_fetch_texel_rgtc(0, (int8_t *)src, i, j, &tmp_r, 2); |
u_format_signed_fetch_texel_rgtc(0, (int8_t *)src + 8, i, j, &tmp_g, 2); |
dst[0] = byte_to_float_tex(tmp_r); |
dst[1] = byte_to_float_tex(tmp_g); |
dst[2] = 0.0; |
dst[3] = 1.0; |
} |
#define TAG(x) u_format_unsigned_##x |
#define TYPE uint8_t |
#define T_MIN 0 |
#define T_MAX 255 |
#include "../../../mesa/main/texcompress_rgtc_tmp.h" |
#undef TYPE |
#undef TAG |
#undef T_MIN |
#undef T_MAX |
#define TAG(x) u_format_signed_##x |
#define TYPE int8_t |
#define T_MIN (int8_t)-128 |
#define T_MAX (int8_t)127 |
#include "../../../mesa/main/texcompress_rgtc_tmp.h" |
#undef TYPE |
#undef TAG |
#undef T_MIN |
#undef T_MAX |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_format_rgtc.h |
---|
0,0 → 1,114 |
/************************************************************************** |
* |
* Copyright 2011 Red Hat Inc. |
* 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 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 |
* THE COPYRIGHT HOLDERS, 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. |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
**************************************************************************/ |
#ifndef U_FORMAT_RGTC_H_ |
#define U_FORMAT_RGTC_H_ |
void |
util_format_rgtc1_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j); |
void |
util_format_rgtc1_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_rgtc1_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_rgtc1_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_rgtc1_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_rgtc1_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j); |
void |
util_format_rgtc1_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j); |
void |
util_format_rgtc1_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_rgtc1_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_rgtc1_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_rgtc1_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_rgtc1_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j); |
void |
util_format_rgtc2_unorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j); |
void |
util_format_rgtc2_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_rgtc2_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_rxtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height, unsigned chan2off); |
void |
util_format_rgtc2_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_rgtc2_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_rgtc2_unorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j); |
void |
util_format_rgtc2_snorm_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j); |
void |
util_format_rgtc2_snorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_rgtc2_snorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_rgtc2_snorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_rxtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height, unsigned chan2off); |
void |
util_format_rgtc2_snorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_rgtc2_snorm_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j); |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_format_s3tc.c |
---|
0,0 → 1,793 |
/************************************************************************** |
* |
* Copyright (C) 1999-2007 Brian Paul All Rights Reserved. |
* Copyright (c) 2008 VMware, Inc. |
* |
* 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, sublicense, |
* 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 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 NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS 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 "u_dl.h" |
#include "u_math.h" |
#include "u_format.h" |
#include "u_format_s3tc.h" |
#include "u_format_srgb.h" |
#if defined(_WIN32) || defined(WIN32) |
#define DXTN_LIBNAME "dxtn.dll" |
#elif defined(__APPLE__) |
#define DXTN_LIBNAME "libtxc_dxtn.dylib" |
#else |
#define DXTN_LIBNAME "libtxc_dxtn.so" |
#endif |
static void |
util_format_dxt1_rgb_fetch_stub(int src_stride, |
const uint8_t *src, |
int col, int row, |
uint8_t *dst) |
{ |
assert(0); |
} |
static void |
util_format_dxt1_rgba_fetch_stub(int src_stride, |
const uint8_t *src, |
int col, int row, |
uint8_t *dst ) |
{ |
assert(0); |
} |
static void |
util_format_dxt3_rgba_fetch_stub(int src_stride, |
const uint8_t *src, |
int col, int row, |
uint8_t *dst ) |
{ |
assert(0); |
} |
static void |
util_format_dxt5_rgba_fetch_stub(int src_stride, |
const uint8_t *src, |
int col, int row, |
uint8_t *dst ) |
{ |
assert(0); |
} |
static void |
util_format_dxtn_pack_stub(int src_comps, |
int width, int height, |
const uint8_t *src, |
enum util_format_dxtn dst_format, |
uint8_t *dst, |
int dst_stride) |
{ |
assert(0); |
} |
boolean util_format_s3tc_enabled = FALSE; |
util_format_dxtn_fetch_t util_format_dxt1_rgb_fetch = util_format_dxt1_rgb_fetch_stub; |
util_format_dxtn_fetch_t util_format_dxt1_rgba_fetch = util_format_dxt1_rgba_fetch_stub; |
util_format_dxtn_fetch_t util_format_dxt3_rgba_fetch = util_format_dxt3_rgba_fetch_stub; |
util_format_dxtn_fetch_t util_format_dxt5_rgba_fetch = util_format_dxt5_rgba_fetch_stub; |
util_format_dxtn_pack_t util_format_dxtn_pack = util_format_dxtn_pack_stub; |
void |
util_format_s3tc_init(void) |
{ |
static boolean first_time = TRUE; |
struct util_dl_library *library = NULL; |
util_dl_proc fetch_2d_texel_rgb_dxt1; |
util_dl_proc fetch_2d_texel_rgba_dxt1; |
util_dl_proc fetch_2d_texel_rgba_dxt3; |
util_dl_proc fetch_2d_texel_rgba_dxt5; |
util_dl_proc tx_compress_dxtn; |
if (!first_time) |
return; |
first_time = FALSE; |
if (util_format_s3tc_enabled) |
return; |
library = util_dl_open(DXTN_LIBNAME); |
if (!library) { |
debug_printf("couldn't open " DXTN_LIBNAME ", software DXTn " |
"compression/decompression unavailable\n"); |
return; |
} |
fetch_2d_texel_rgb_dxt1 = |
util_dl_get_proc_address(library, "fetch_2d_texel_rgb_dxt1"); |
fetch_2d_texel_rgba_dxt1 = |
util_dl_get_proc_address(library, "fetch_2d_texel_rgba_dxt1"); |
fetch_2d_texel_rgba_dxt3 = |
util_dl_get_proc_address(library, "fetch_2d_texel_rgba_dxt3"); |
fetch_2d_texel_rgba_dxt5 = |
util_dl_get_proc_address(library, "fetch_2d_texel_rgba_dxt5"); |
tx_compress_dxtn = |
util_dl_get_proc_address(library, "tx_compress_dxtn"); |
if (!util_format_dxt1_rgb_fetch || |
!util_format_dxt1_rgba_fetch || |
!util_format_dxt3_rgba_fetch || |
!util_format_dxt5_rgba_fetch || |
!util_format_dxtn_pack) { |
debug_printf("couldn't reference all symbols in " DXTN_LIBNAME |
", software DXTn compression/decompression " |
"unavailable\n"); |
util_dl_close(library); |
return; |
} |
util_format_dxt1_rgb_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgb_dxt1; |
util_format_dxt1_rgba_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgba_dxt1; |
util_format_dxt3_rgba_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgba_dxt3; |
util_format_dxt5_rgba_fetch = (util_format_dxtn_fetch_t)fetch_2d_texel_rgba_dxt5; |
util_format_dxtn_pack = (util_format_dxtn_pack_t)tx_compress_dxtn; |
util_format_s3tc_enabled = TRUE; |
} |
/* |
* Pixel fetch. |
*/ |
void |
util_format_dxt1_rgb_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
util_format_dxt1_rgb_fetch(0, src, i, j, dst); |
} |
void |
util_format_dxt1_rgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
util_format_dxt1_rgba_fetch(0, src, i, j, dst); |
} |
void |
util_format_dxt3_rgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
util_format_dxt3_rgba_fetch(0, src, i, j, dst); |
} |
void |
util_format_dxt5_rgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
util_format_dxt5_rgba_fetch(0, src, i, j, dst); |
} |
void |
util_format_dxt1_rgb_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
uint8_t tmp[4]; |
util_format_dxt1_rgb_fetch(0, src, i, j, tmp); |
dst[0] = ubyte_to_float(tmp[0]); |
dst[1] = ubyte_to_float(tmp[1]); |
dst[2] = ubyte_to_float(tmp[2]); |
dst[3] = 1.0; |
} |
void |
util_format_dxt1_rgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
uint8_t tmp[4]; |
util_format_dxt1_rgba_fetch(0, src, i, j, tmp); |
dst[0] = ubyte_to_float(tmp[0]); |
dst[1] = ubyte_to_float(tmp[1]); |
dst[2] = ubyte_to_float(tmp[2]); |
dst[3] = ubyte_to_float(tmp[3]); |
} |
void |
util_format_dxt3_rgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
uint8_t tmp[4]; |
util_format_dxt3_rgba_fetch(0, src, i, j, tmp); |
dst[0] = ubyte_to_float(tmp[0]); |
dst[1] = ubyte_to_float(tmp[1]); |
dst[2] = ubyte_to_float(tmp[2]); |
dst[3] = ubyte_to_float(tmp[3]); |
} |
void |
util_format_dxt5_rgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
uint8_t tmp[4]; |
util_format_dxt5_rgba_fetch(0, src, i, j, tmp); |
dst[0] = ubyte_to_float(tmp[0]); |
dst[1] = ubyte_to_float(tmp[1]); |
dst[2] = ubyte_to_float(tmp[2]); |
dst[3] = ubyte_to_float(tmp[3]); |
} |
/* |
* Block decompression. |
*/ |
static INLINE void |
util_format_dxtn_rgb_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height, |
util_format_dxtn_fetch_t fetch, |
unsigned block_size, boolean srgb) |
{ |
const unsigned bw = 4, bh = 4, comps = 4; |
unsigned x, y, i, j; |
for(y = 0; y < height; y += bh) { |
const uint8_t *src = src_row; |
for(x = 0; x < width; x += bw) { |
for(j = 0; j < bh; ++j) { |
for(i = 0; i < bw; ++i) { |
uint8_t *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*comps; |
fetch(0, src, i, j, dst); |
if (srgb) { |
dst[0] = util_format_srgb_to_linear_8unorm(dst[0]); |
dst[1] = util_format_srgb_to_linear_8unorm(dst[1]); |
dst[2] = util_format_srgb_to_linear_8unorm(dst[2]); |
} |
} |
} |
src += block_size; |
} |
src_row += src_stride; |
} |
} |
void |
util_format_dxt1_rgb_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride, |
src_row, src_stride, |
width, height, |
util_format_dxt1_rgb_fetch, |
8, FALSE); |
} |
void |
util_format_dxt1_rgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride, |
src_row, src_stride, |
width, height, |
util_format_dxt1_rgba_fetch, |
8, FALSE); |
} |
void |
util_format_dxt3_rgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride, |
src_row, src_stride, |
width, height, |
util_format_dxt3_rgba_fetch, |
16, FALSE); |
} |
void |
util_format_dxt5_rgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride, |
src_row, src_stride, |
width, height, |
util_format_dxt5_rgba_fetch, |
16, FALSE); |
} |
static INLINE void |
util_format_dxtn_rgb_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height, |
util_format_dxtn_fetch_t fetch, |
unsigned block_size, boolean srgb) |
{ |
unsigned x, y, i, j; |
for(y = 0; y < height; y += 4) { |
const uint8_t *src = src_row; |
for(x = 0; x < width; x += 4) { |
for(j = 0; j < 4; ++j) { |
for(i = 0; i < 4; ++i) { |
float *dst = dst_row + (y + j)*dst_stride/sizeof(*dst_row) + (x + i)*4; |
uint8_t tmp[4]; |
fetch(0, src, i, j, tmp); |
if (srgb) { |
dst[0] = util_format_srgb_8unorm_to_linear_float(tmp[0]); |
dst[1] = util_format_srgb_8unorm_to_linear_float(tmp[1]); |
dst[2] = util_format_srgb_8unorm_to_linear_float(tmp[2]); |
} |
else { |
dst[0] = ubyte_to_float(tmp[0]); |
dst[1] = ubyte_to_float(tmp[1]); |
dst[2] = ubyte_to_float(tmp[2]); |
} |
dst[3] = ubyte_to_float(tmp[3]); |
} |
} |
src += block_size; |
} |
src_row += src_stride; |
} |
} |
void |
util_format_dxt1_rgb_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride, |
src_row, src_stride, |
width, height, |
util_format_dxt1_rgb_fetch, |
8, FALSE); |
} |
void |
util_format_dxt1_rgba_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride, |
src_row, src_stride, |
width, height, |
util_format_dxt1_rgba_fetch, |
8, FALSE); |
} |
void |
util_format_dxt3_rgba_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride, |
src_row, src_stride, |
width, height, |
util_format_dxt3_rgba_fetch, |
16, FALSE); |
} |
void |
util_format_dxt5_rgba_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride, |
src_row, src_stride, |
width, height, |
util_format_dxt5_rgba_fetch, |
16, FALSE); |
} |
/* |
* Block compression. |
*/ |
static INLINE void |
util_format_dxtn_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src, unsigned src_stride, |
unsigned width, unsigned height, |
enum util_format_dxtn format, |
unsigned block_size, boolean srgb) |
{ |
const unsigned bw = 4, bh = 4, comps = 4; |
unsigned x, y, i, j, k; |
for(y = 0; y < height; y += bh) { |
uint8_t *dst = dst_row; |
for(x = 0; x < width; x += bw) { |
uint8_t tmp[4][4][4]; /* [bh][bw][comps] */ |
for(j = 0; j < bh; ++j) { |
for(i = 0; i < bw; ++i) { |
uint8_t src_tmp; |
for(k = 0; k < 3; ++k) { |
src_tmp = src[(y + j)*src_stride/sizeof(*src) + (x+i)*comps + k]; |
if (srgb) { |
tmp[j][i][k] = util_format_linear_to_srgb_8unorm(src_tmp); |
} |
else { |
tmp[j][i][k] = src_tmp; |
} |
} |
/* for sake of simplicity there's an unneeded 4th component for dxt1_rgb */ |
tmp[j][i][3] = src[(y + j)*src_stride/sizeof(*src) + (x+i)*comps + 3]; |
} |
} |
/* even for dxt1_rgb have 4 src comps */ |
util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], format, dst, 0); |
dst += block_size; |
} |
dst_row += dst_stride / sizeof(*dst_row); |
} |
} |
void |
util_format_dxt1_rgb_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src, src_stride, |
width, height, UTIL_FORMAT_DXT1_RGB, |
8, FALSE); |
} |
void |
util_format_dxt1_rgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src, src_stride, |
width, height, UTIL_FORMAT_DXT1_RGBA, |
8, FALSE); |
} |
void |
util_format_dxt3_rgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src, src_stride, |
width, height, UTIL_FORMAT_DXT3_RGBA, |
16, FALSE); |
} |
void |
util_format_dxt5_rgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src, src_stride, |
width, height, UTIL_FORMAT_DXT5_RGBA, |
16, FALSE); |
} |
static INLINE void |
util_format_dxtn_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src, unsigned src_stride, |
unsigned width, unsigned height, |
enum util_format_dxtn format, |
unsigned block_size, boolean srgb) |
{ |
unsigned x, y, i, j, k; |
for(y = 0; y < height; y += 4) { |
uint8_t *dst = dst_row; |
for(x = 0; x < width; x += 4) { |
uint8_t tmp[4][4][4]; |
for(j = 0; j < 4; ++j) { |
for(i = 0; i < 4; ++i) { |
float src_tmp; |
for(k = 0; k < 3; ++k) { |
src_tmp = src[(y + j)*src_stride/sizeof(*src) + (x+i)*4 + k]; |
if (srgb) { |
tmp[j][i][k] = util_format_linear_float_to_srgb_8unorm(src_tmp); |
} |
else { |
tmp[j][i][k] = float_to_ubyte(src_tmp); |
} |
} |
/* for sake of simplicity there's an unneeded 4th component for dxt1_rgb */ |
src_tmp = src[(y + j)*src_stride/sizeof(*src) + (x+i)*4 + 3]; |
tmp[j][i][3] = float_to_ubyte(src_tmp); |
} |
} |
util_format_dxtn_pack(4, 4, 4, &tmp[0][0][0], format, dst, 0); |
dst += block_size; |
} |
dst_row += 4*dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_dxt1_rgb_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src, src_stride, |
width, height, UTIL_FORMAT_DXT1_RGB, |
8, FALSE); |
} |
void |
util_format_dxt1_rgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src, src_stride, |
width, height, UTIL_FORMAT_DXT1_RGBA, |
8, FALSE); |
} |
void |
util_format_dxt3_rgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src, src_stride, |
width, height, UTIL_FORMAT_DXT3_RGBA, |
16, FALSE); |
} |
void |
util_format_dxt5_rgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src, src_stride, |
width, height, UTIL_FORMAT_DXT5_RGBA, |
16, FALSE); |
} |
/* |
* SRGB variants. |
*/ |
void |
util_format_dxt1_srgb_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
uint8_t tmp[4]; |
util_format_dxt1_rgb_fetch(0, src, i, j, tmp); |
dst[0] = util_format_srgb_to_linear_8unorm(tmp[0]); |
dst[1] = util_format_srgb_to_linear_8unorm(tmp[1]); |
dst[2] = util_format_srgb_to_linear_8unorm(tmp[2]); |
dst[3] = 255; |
} |
void |
util_format_dxt1_srgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
uint8_t tmp[4]; |
util_format_dxt1_rgba_fetch(0, src, i, j, tmp); |
dst[0] = util_format_srgb_to_linear_8unorm(tmp[0]); |
dst[1] = util_format_srgb_to_linear_8unorm(tmp[1]); |
dst[2] = util_format_srgb_to_linear_8unorm(tmp[2]); |
dst[3] = tmp[3]; |
} |
void |
util_format_dxt3_srgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
uint8_t tmp[4]; |
util_format_dxt3_rgba_fetch(0, src, i, j, tmp); |
dst[0] = util_format_srgb_to_linear_8unorm(tmp[0]); |
dst[1] = util_format_srgb_to_linear_8unorm(tmp[1]); |
dst[2] = util_format_srgb_to_linear_8unorm(tmp[2]); |
dst[3] = tmp[3]; |
} |
void |
util_format_dxt5_srgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
uint8_t tmp[4]; |
util_format_dxt5_rgba_fetch(0, src, i, j, tmp); |
dst[0] = util_format_srgb_to_linear_8unorm(tmp[0]); |
dst[1] = util_format_srgb_to_linear_8unorm(tmp[1]); |
dst[2] = util_format_srgb_to_linear_8unorm(tmp[2]); |
dst[3] = tmp[3]; |
} |
void |
util_format_dxt1_srgb_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
uint8_t tmp[4]; |
util_format_dxt1_rgb_fetch(0, src, i, j, tmp); |
dst[0] = util_format_srgb_8unorm_to_linear_float(tmp[0]); |
dst[1] = util_format_srgb_8unorm_to_linear_float(tmp[1]); |
dst[2] = util_format_srgb_8unorm_to_linear_float(tmp[2]); |
dst[3] = 1.0f; |
} |
void |
util_format_dxt1_srgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
uint8_t tmp[4]; |
util_format_dxt1_rgba_fetch(0, src, i, j, tmp); |
dst[0] = util_format_srgb_8unorm_to_linear_float(tmp[0]); |
dst[1] = util_format_srgb_8unorm_to_linear_float(tmp[1]); |
dst[2] = util_format_srgb_8unorm_to_linear_float(tmp[2]); |
dst[3] = ubyte_to_float(tmp[3]); |
} |
void |
util_format_dxt3_srgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
uint8_t tmp[4]; |
util_format_dxt3_rgba_fetch(0, src, i, j, tmp); |
dst[0] = util_format_srgb_8unorm_to_linear_float(tmp[0]); |
dst[1] = util_format_srgb_8unorm_to_linear_float(tmp[1]); |
dst[2] = util_format_srgb_8unorm_to_linear_float(tmp[2]); |
dst[3] = ubyte_to_float(tmp[3]); |
} |
void |
util_format_dxt5_srgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j) |
{ |
uint8_t tmp[4]; |
util_format_dxt5_rgba_fetch(0, src, i, j, tmp); |
dst[0] = util_format_srgb_8unorm_to_linear_float(tmp[0]); |
dst[1] = util_format_srgb_8unorm_to_linear_float(tmp[1]); |
dst[2] = util_format_srgb_8unorm_to_linear_float(tmp[2]); |
dst[3] = ubyte_to_float(tmp[3]); |
} |
void |
util_format_dxt1_srgb_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride, |
src_row, src_stride, |
width, height, |
util_format_dxt1_rgb_fetch, |
8, TRUE); |
} |
void |
util_format_dxt1_srgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride, |
src_row, src_stride, |
width, height, |
util_format_dxt1_rgba_fetch, |
8, TRUE); |
} |
void |
util_format_dxt3_srgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride, |
src_row, src_stride, |
width, height, |
util_format_dxt3_rgba_fetch, |
16, TRUE); |
} |
void |
util_format_dxt5_srgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_dxtn_rgb_unpack_rgba_8unorm(dst_row, dst_stride, |
src_row, src_stride, |
width, height, |
util_format_dxt5_rgba_fetch, |
16, TRUE); |
} |
void |
util_format_dxt1_srgb_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride, |
src_row, src_stride, |
width, height, |
util_format_dxt1_rgb_fetch, |
8, TRUE); |
} |
void |
util_format_dxt1_srgba_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride, |
src_row, src_stride, |
width, height, |
util_format_dxt1_rgba_fetch, |
8, TRUE); |
} |
void |
util_format_dxt3_srgba_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride, |
src_row, src_stride, |
width, height, |
util_format_dxt3_rgba_fetch, |
16, TRUE); |
} |
void |
util_format_dxt5_srgba_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_dxtn_rgb_unpack_rgba_float(dst_row, dst_stride, |
src_row, src_stride, |
width, height, |
util_format_dxt5_rgba_fetch, |
16, TRUE); |
} |
void |
util_format_dxt1_srgb_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, |
width, height, UTIL_FORMAT_DXT1_RGB, |
8, TRUE); |
} |
void |
util_format_dxt1_srgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, |
width, height, UTIL_FORMAT_DXT1_RGBA, |
8, TRUE); |
} |
void |
util_format_dxt3_srgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, |
width, height, UTIL_FORMAT_DXT3_RGBA, |
16, TRUE); |
} |
void |
util_format_dxt5_srgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_dxtn_pack_rgba_8unorm(dst_row, dst_stride, src_row, src_stride, |
width, height, UTIL_FORMAT_DXT5_RGBA, |
16, TRUE); |
} |
void |
util_format_dxt1_srgb_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, |
width, height, UTIL_FORMAT_DXT1_RGB, |
8, TRUE); |
} |
void |
util_format_dxt1_srgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, |
width, height, UTIL_FORMAT_DXT1_RGBA, |
8, TRUE); |
} |
void |
util_format_dxt3_srgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, |
width, height, UTIL_FORMAT_DXT3_RGBA, |
16, TRUE); |
} |
void |
util_format_dxt5_srgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_dxtn_pack_rgba_float(dst_row, dst_stride, src_row, src_stride, |
width, height, UTIL_FORMAT_DXT5_RGBA, |
16, TRUE); |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_format_s3tc.h |
---|
0,0 → 1,218 |
/************************************************************************** |
* |
* Copyright 2010 VMware, Inc. |
* 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 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 |
* THE COPYRIGHT HOLDERS, 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. |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
**************************************************************************/ |
#ifndef U_FORMAT_S3TC_H_ |
#define U_FORMAT_S3TC_H_ |
#include "pipe/p_compiler.h" |
enum util_format_dxtn { |
UTIL_FORMAT_DXT1_RGB = 0x83F0, |
UTIL_FORMAT_DXT1_RGBA = 0x83F1, |
UTIL_FORMAT_DXT3_RGBA = 0x83F2, |
UTIL_FORMAT_DXT5_RGBA = 0x83F3 |
}; |
typedef void |
(*util_format_dxtn_fetch_t)( int src_stride, |
const uint8_t *src, |
int col, int row, |
uint8_t *dst ); |
typedef void |
(*util_format_dxtn_pack_t)( int src_comps, |
int width, int height, |
const uint8_t *src, |
enum util_format_dxtn dst_format, |
uint8_t *dst, |
int dst_stride); |
extern boolean util_format_s3tc_enabled; |
extern util_format_dxtn_fetch_t util_format_dxt1_rgb_fetch; |
extern util_format_dxtn_fetch_t util_format_dxt1_rgba_fetch; |
extern util_format_dxtn_fetch_t util_format_dxt3_rgba_fetch; |
extern util_format_dxtn_fetch_t util_format_dxt5_rgba_fetch; |
extern util_format_dxtn_pack_t util_format_dxtn_pack; |
void |
util_format_s3tc_init(void); |
void |
util_format_dxt1_rgb_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt1_rgb_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt1_rgb_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j); |
void |
util_format_dxt1_rgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt1_rgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt1_rgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j); |
void |
util_format_dxt3_rgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt3_rgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt3_rgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j); |
void |
util_format_dxt5_rgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt5_rgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt5_rgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j); |
void |
util_format_dxt1_srgb_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt1_srgb_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt1_srgb_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j); |
void |
util_format_dxt1_srgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt1_srgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt1_srgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j); |
void |
util_format_dxt3_srgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt3_srgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt3_srgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j); |
void |
util_format_dxt5_srgba_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt5_srgba_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt5_srgba_fetch_rgba_8unorm(uint8_t *dst, const uint8_t *src, unsigned i, unsigned j); |
void |
util_format_dxt1_rgb_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt1_rgb_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt1_rgb_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j); |
void |
util_format_dxt1_rgba_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt1_rgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt1_rgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j); |
void |
util_format_dxt3_rgba_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt3_rgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt3_rgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j); |
void |
util_format_dxt5_rgba_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt5_rgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt5_rgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j); |
void |
util_format_dxt1_srgb_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt1_srgb_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt1_srgb_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j); |
void |
util_format_dxt1_srgba_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt1_srgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt1_srgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j); |
void |
util_format_dxt3_srgba_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt3_srgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt3_srgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j); |
void |
util_format_dxt5_srgba_unpack_rgba_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt5_srgba_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_dxt5_srgba_fetch_rgba_float(float *dst, const uint8_t *src, unsigned i, unsigned j); |
#endif /* U_FORMAT_S3TC_H_ */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_format_srgb.h |
---|
0,0 → 1,111 |
/************************************************************************** |
* |
* Copyright 2010 VMware, Inc. |
* 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 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 |
* THE COPYRIGHT HOLDERS, 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. |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
**************************************************************************/ |
/** |
* @file |
* SRGB translation. |
* |
* @author Brian Paul <brianp@vmware.com> |
* @author Michal Krol <michal@vmware.com> |
* @author Jose Fonseca <jfonseca@vmware.com> |
*/ |
#ifndef U_FORMAT_SRGB_H_ |
#define U_FORMAT_SRGB_H_ |
#include "pipe/p_compiler.h" |
#include "u_math.h" |
extern const float |
util_format_srgb_8unorm_to_linear_float_table[256]; |
extern const uint8_t |
util_format_srgb_to_linear_8unorm_table[256]; |
extern const uint8_t |
util_format_linear_to_srgb_8unorm_table[256]; |
/** |
* Convert a unclamped linear float to srgb value in the [0,255]. |
* XXX this hasn't been tested (render to srgb surface). |
* XXX this needs optimization. |
*/ |
static INLINE uint8_t |
util_format_linear_float_to_srgb_8unorm(float x) |
{ |
if (x >= 1.0f) |
return 255; |
else if (x >= 0.0031308f) |
return float_to_ubyte(1.055f * powf(x, 0.41666f) - 0.055f); |
else if (x > 0.0f) |
return float_to_ubyte(12.92f * x); |
else |
return 0; |
} |
/** |
* Convert an 8-bit sRGB value from non-linear space to a |
* linear RGB value in [0, 1]. |
* Implemented with a 256-entry lookup table. |
*/ |
static INLINE float |
util_format_srgb_8unorm_to_linear_float(uint8_t x) |
{ |
return util_format_srgb_8unorm_to_linear_float_table[x]; |
} |
/* |
* XXX These 2 functions probably don't make a lot of sense (but lots |
* of potential callers which most likely all don't make sense neither) |
*/ |
/** |
* Convert a 8bit normalized value from linear to srgb. |
*/ |
static INLINE uint8_t |
util_format_linear_to_srgb_8unorm(uint8_t x) |
{ |
return util_format_linear_to_srgb_8unorm_table[x]; |
} |
/** |
* Convert a 8bit normalized value from srgb to linear. |
*/ |
static INLINE uint8_t |
util_format_srgb_to_linear_8unorm(uint8_t x) |
{ |
return util_format_srgb_to_linear_8unorm_table[x]; |
} |
#endif /* U_FORMAT_SRGB_H_ */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_format_srgb.py |
---|
0,0 → 1,100 |
#!/usr/bin/env python |
CopyRight = ''' |
/************************************************************************** |
* |
* Copyright 2010 VMware, Inc. |
* 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 VMWARE 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. |
* |
**************************************************************************/ |
/** |
* @file |
* SRGB translation. |
* |
* @author Brian Paul <brianp@vmware.com> |
* @author Michal Krol <michal@vmware.com> |
* @author Jose Fonseca <jfonseca@vmware.com> |
*/ |
''' |
import math |
def srgb_to_linear(x): |
if x <= 0.04045: |
return x / 12.92 |
else: |
return math.pow((x + 0.055) / 1.055, 2.4) |
def linear_to_srgb(x): |
if x >= 0.0031308: |
return 1.055 * math.pow(x, 0.41666) - 0.055 |
else: |
return 12.92 * x |
def generate_srgb_tables(): |
print 'const float' |
print 'util_format_srgb_8unorm_to_linear_float_table[256] = {' |
for j in range(0, 256, 4): |
print ' ', |
for i in range(j, j + 4): |
print '%.7e,' % (srgb_to_linear(i / 255.0),), |
print '};' |
print 'const uint8_t' |
print 'util_format_srgb_to_linear_8unorm_table[256] = {' |
for j in range(0, 256, 16): |
print ' ', |
for i in range(j, j + 16): |
print '%3u,' % (int(srgb_to_linear(i / 255.0) * 255.0 + 0.5),), |
print '};' |
print 'const uint8_t' |
print 'util_format_linear_to_srgb_8unorm_table[256] = {' |
for j in range(0, 256, 16): |
print ' ', |
for i in range(j, j + 16): |
print '%3u,' % (int(linear_to_srgb(i / 255.0) * 255.0 + 0.5),), |
print '};' |
def main(): |
print '/* This file is autogenerated by u_format_srgb.py. Do not edit directly. */' |
# This will print the copyright message on the top of this file |
print CopyRight.strip() |
print '#include "u_format_srgb.h"' |
generate_srgb_tables() |
if __name__ == '__main__': |
main() |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_format_table.py |
---|
0,0 → 1,219 |
#!/usr/bin/env python |
CopyRight = ''' |
/************************************************************************** |
* |
* Copyright 2010 VMware, Inc. |
* 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 VMWARE 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. |
* |
**************************************************************************/ |
''' |
import sys |
from u_format_parse import * |
import u_format_pack |
def layout_map(layout): |
return 'UTIL_FORMAT_LAYOUT_' + str(layout).upper() |
def colorspace_map(colorspace): |
return 'UTIL_FORMAT_COLORSPACE_' + str(colorspace).upper() |
colorspace_channels_map = { |
'rgb': ['r', 'g', 'b', 'a'], |
'srgb': ['sr', 'sg', 'sb', 'a'], |
'zs': ['z', 's'], |
'yuv': ['y', 'u', 'v'], |
} |
type_map = { |
VOID: "UTIL_FORMAT_TYPE_VOID", |
UNSIGNED: "UTIL_FORMAT_TYPE_UNSIGNED", |
SIGNED: "UTIL_FORMAT_TYPE_SIGNED", |
FIXED: "UTIL_FORMAT_TYPE_FIXED", |
FLOAT: "UTIL_FORMAT_TYPE_FLOAT", |
} |
def bool_map(value): |
if value: |
return "TRUE" |
else: |
return "FALSE" |
swizzle_map = { |
SWIZZLE_X: "UTIL_FORMAT_SWIZZLE_X", |
SWIZZLE_Y: "UTIL_FORMAT_SWIZZLE_Y", |
SWIZZLE_Z: "UTIL_FORMAT_SWIZZLE_Z", |
SWIZZLE_W: "UTIL_FORMAT_SWIZZLE_W", |
SWIZZLE_0: "UTIL_FORMAT_SWIZZLE_0", |
SWIZZLE_1: "UTIL_FORMAT_SWIZZLE_1", |
SWIZZLE_NONE: "UTIL_FORMAT_SWIZZLE_NONE", |
} |
def write_format_table(formats): |
print '/* This file is autogenerated by u_format_table.py from u_format.csv. Do not edit directly. */' |
# This will print the copyright message on the top of this file |
print CopyRight.strip() |
print '#include "u_format.h"' |
print '#include "u_format_s3tc.h"' |
print '#include "u_format_rgtc.h"' |
print '#include "u_format_latc.h"' |
print '#include "u_format_etc.h"' |
u_format_pack.generate(formats) |
for format in formats: |
print 'const struct util_format_description' |
print 'util_format_%s_description = {' % (format.short_name(),) |
print " %s," % (format.name,) |
print " \"%s\"," % (format.name,) |
print " \"%s\"," % (format.short_name(),) |
print " {%u, %u, %u},\t/* block */" % (format.block_width, format.block_height, format.block_size()) |
print " %s," % (layout_map(format.layout),) |
print " %u,\t/* nr_channels */" % (format.nr_channels(),) |
print " %s,\t/* is_array */" % (bool_map(format.is_array()),) |
print " %s,\t/* is_bitmask */" % (bool_map(format.is_bitmask()),) |
print " %s,\t/* is_mixed */" % (bool_map(format.is_mixed()),) |
print " {" |
for i in range(4): |
channel = format.channels[i] |
if i < 3: |
sep = "," |
else: |
sep = "" |
if channel.size: |
print " {%s, %s, %s, %u, %u}%s\t/* %s = %s */" % (type_map[channel.type], bool_map(channel.norm), bool_map(channel.pure), channel.size, channel.shift, sep, "xyzw"[i], channel.name) |
else: |
print " {0, 0, 0, 0, 0}%s" % (sep,) |
print " }," |
print " {" |
for i in range(4): |
swizzle = format.swizzles[i] |
if i < 3: |
sep = "," |
else: |
sep = "" |
try: |
comment = colorspace_channels_map[format.colorspace][i] |
except (KeyError, IndexError): |
comment = 'ignored' |
print " %s%s\t/* %s */" % (swizzle_map[swizzle], sep, comment) |
print " }," |
print " %s," % (colorspace_map(format.colorspace),) |
if format.colorspace != ZS and format.channels[0].pure == False: |
print " &util_format_%s_unpack_rgba_8unorm," % format.short_name() |
print " &util_format_%s_pack_rgba_8unorm," % format.short_name() |
if format.layout == 's3tc' or format.layout == 'rgtc': |
print " &util_format_%s_fetch_rgba_8unorm," % format.short_name() |
else: |
print " NULL, /* fetch_rgba_8unorm */" |
print " &util_format_%s_unpack_rgba_float," % format.short_name() |
print " &util_format_%s_pack_rgba_float," % format.short_name() |
print " &util_format_%s_fetch_rgba_float," % format.short_name() |
else: |
print " NULL, /* unpack_rgba_8unorm */" |
print " NULL, /* pack_rgba_8unorm */" |
print " NULL, /* fetch_rgba_8unorm */" |
print " NULL, /* unpack_rgba_float */" |
print " NULL, /* pack_rgba_float */" |
print " NULL, /* fetch_rgba_float */" |
if format.colorspace == ZS and format.swizzles[0] != SWIZZLE_NONE: |
print " &util_format_%s_unpack_z_32unorm," % format.short_name() |
print " &util_format_%s_pack_z_32unorm," % format.short_name() |
print " &util_format_%s_unpack_z_float," % format.short_name() |
print " &util_format_%s_pack_z_float," % format.short_name() |
else: |
print " NULL, /* unpack_z_32unorm */" |
print " NULL, /* pack_z_32unorm */" |
print " NULL, /* unpack_z_float */" |
print " NULL, /* pack_z_float */" |
if format.colorspace == ZS and format.swizzles[1] != SWIZZLE_NONE: |
print " &util_format_%s_unpack_s_8uint," % format.short_name() |
print " &util_format_%s_pack_s_8uint," % format.short_name() |
else: |
print " NULL, /* unpack_s_8uint */" |
print " NULL, /* pack_s_8uint */" |
if format.colorspace != ZS and format.channels[0].pure == True and format.channels[0].type == UNSIGNED: |
print " &util_format_%s_unpack_unsigned, /* unpack_rgba_uint */" % format.short_name() |
print " &util_format_%s_pack_unsigned, /* pack_rgba_uint */" % format.short_name() |
print " &util_format_%s_unpack_signed, /* unpack_rgba_sint */" % format.short_name() |
print " &util_format_%s_pack_signed, /* pack_rgba_sint */" % format.short_name() |
print " &util_format_%s_fetch_unsigned, /* fetch_rgba_uint */" % format.short_name() |
print " NULL /* fetch_rgba_sint */" |
elif format.colorspace != ZS and format.channels[0].pure == True and format.channels[0].type == SIGNED: |
print " &util_format_%s_unpack_unsigned, /* unpack_rgba_uint */" % format.short_name() |
print " &util_format_%s_pack_unsigned, /* pack_rgba_uint */" % format.short_name() |
print " &util_format_%s_unpack_signed, /* unpack_rgba_sint */" % format.short_name() |
print " &util_format_%s_pack_signed, /* pack_rgba_sint */" % format.short_name() |
print " NULL, /* fetch_rgba_uint */" |
print " &util_format_%s_fetch_signed /* fetch_rgba_sint */" % format.short_name() |
else: |
print " NULL, /* unpack_rgba_uint */" |
print " NULL, /* pack_rgba_uint */" |
print " NULL, /* unpack_rgba_sint */" |
print " NULL, /* pack_rgba_sint */" |
print " NULL, /* fetch_rgba_uint */" |
print " NULL /* fetch_rgba_sint */" |
print "};" |
print "const struct util_format_description *" |
print "util_format_description(enum pipe_format format)" |
print "{" |
print " if (format >= PIPE_FORMAT_COUNT) {" |
print " return NULL;" |
print " }" |
print " switch (format) {" |
for format in formats: |
print " case %s:" % format.name |
print " return &util_format_%s_description;" % (format.short_name(),) |
print " default:" |
print " return NULL;" |
print " }" |
print "}" |
def main(): |
formats = [] |
for arg in sys.argv[1:]: |
formats.extend(parse(arg)) |
write_format_table(formats) |
if __name__ == '__main__': |
main() |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_format_tests.c |
---|
0,0 → 1,1011 |
/************************************************************************** |
* |
* Copyright 2009-2010 VMware, Inc. |
* 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 VMWARE 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 <math.h> |
#include <float.h> |
#include "pipe/p_config.h" |
#include "u_memory.h" |
#include "u_format_tests.h" |
/* |
* Helper macros to create the packed bytes for longer words. |
*/ |
#define PACKED_1x8(x) {x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} |
#define PACKED_2x8(x, y) {x, y, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} |
#define PACKED_3x8(x, y, z) {x, y, z, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} |
#define PACKED_4x8(x, y, z, w) {x, y, z, w, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} |
#define PACKED_8x8(a, b, c, d, e, f, g, h) {a, b, c, d, e, f, g, h, 0, 0, 0, 0, 0, 0, 0, 0} |
#define PACKED_1x16(x) {(x) & 0xff, (x) >> 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} |
#define PACKED_2x16(x, y) {(x) & 0xff, (x) >> 8, (y) & 0xff, (y) >> 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} |
#define PACKED_3x16(x, y, z) {(x) & 0xff, (x) >> 8, (y) & 0xff, (y) >> 8, (z) & 0xff, (z) >> 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} |
#define PACKED_4x16(x, y, z, w) {(x) & 0xff, (x) >> 8, (y) & 0xff, (y) >> 8, (z) & 0xff, (z) >> 8, (w) & 0xff, (w) >> 8, 0, 0, 0, 0, 0, 0, 0, 0} |
#define PACKED_1x32(x) {(x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, (x) >> 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} |
#define PACKED_2x32(x, y) {(x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, (x) >> 24, (y) & 0xff, ((y) >> 8) & 0xff, ((y) >> 16) & 0xff, (y) >> 24, 0, 0, 0, 0, 0, 0, 0, 0} |
#define PACKED_3x32(x, y, z) {(x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, (x) >> 24, (y) & 0xff, ((y) >> 8) & 0xff, ((y) >> 16) & 0xff, (y) >> 24, (z) & 0xff, ((z) >> 8) & 0xff, ((z) >> 16) & 0xff, (z) >> 24, 0, 0, 0, 0} |
#define PACKED_4x32(x, y, z, w) {(x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, (x) >> 24, (y) & 0xff, ((y) >> 8) & 0xff, ((y) >> 16) & 0xff, (y) >> 24, (z) & 0xff, ((z) >> 8) & 0xff, ((z) >> 16) & 0xff, (z) >> 24, (w) & 0xff, ((w) >> 8) & 0xff, ((w) >> 16) & 0xff, (w) >> 24} |
#define UNPACKED_1x1(r, g, b, a) \ |
{{{r, g, b, a}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, \ |
{{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, \ |
{{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, \ |
{{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}} |
#define UNPACKED_2x1(r0, g0, b0, a0, r1, g1, b1, a1) \ |
{{{r0, g0, b0, a0}, {r1, g1, b1, a1}, {0, 0, 0, 0}, {0, 0, 0, 0}}, \ |
{{ 0, 0, 0, 0}, { 0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, \ |
{{ 0, 0, 0, 0}, { 0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, \ |
{{ 0, 0, 0, 0}, { 0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}} |
/** |
* Test cases. |
* |
* These were manually entered. We could generate these |
* |
* To keep this to a we cover only the corner cases, which should produce |
* good enough coverage since that pixel format transformations are afine for |
* non SRGB formats. |
*/ |
const struct util_format_test_case |
util_format_test_cases[] = |
{ |
/* |
* 32-bit rendertarget formats |
*/ |
{PIPE_FORMAT_B8G8R8A8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), UNPACKED_1x1(0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_B8G8R8A8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x000000ff), UNPACKED_1x1(0.0, 0.0, 1.0, 0.0)}, |
{PIPE_FORMAT_B8G8R8A8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x0000ff00), UNPACKED_1x1(0.0, 1.0, 0.0, 0.0)}, |
{PIPE_FORMAT_B8G8R8A8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00ff0000), UNPACKED_1x1(1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_B8G8R8A8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xff000000), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_B8G8R8A8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xffffffff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_B8G8R8X8_UNORM, PACKED_1x32(0x00ffffff), PACKED_1x32(0x00000000), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_B8G8R8X8_UNORM, PACKED_1x32(0x00ffffff), PACKED_1x32(0x000000ff), UNPACKED_1x1(0.0, 0.0, 1.0, 1.0)}, |
{PIPE_FORMAT_B8G8R8X8_UNORM, PACKED_1x32(0x00ffffff), PACKED_1x32(0x0000ff00), UNPACKED_1x1(0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_B8G8R8X8_UNORM, PACKED_1x32(0x00ffffff), PACKED_1x32(0x00ff0000), UNPACKED_1x1(1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_B8G8R8X8_UNORM, PACKED_1x32(0x00ffffff), PACKED_1x32(0xff000000), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_B8G8R8X8_UNORM, PACKED_1x32(0x00ffffff), PACKED_1x32(0xffffffff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_A8R8G8B8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), UNPACKED_1x1(0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_A8R8G8B8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x000000ff), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_A8R8G8B8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x0000ff00), UNPACKED_1x1(1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_A8R8G8B8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00ff0000), UNPACKED_1x1(0.0, 1.0, 0.0, 0.0)}, |
{PIPE_FORMAT_A8R8G8B8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xff000000), UNPACKED_1x1(0.0, 0.0, 1.0, 0.0)}, |
{PIPE_FORMAT_A8R8G8B8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xffffffff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_X8R8G8B8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0x00000000), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_X8R8G8B8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0x000000ff), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_X8R8G8B8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0x0000ff00), UNPACKED_1x1(1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_X8R8G8B8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0x00ff0000), UNPACKED_1x1(0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_X8R8G8B8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0xff000000), UNPACKED_1x1(0.0, 0.0, 1.0, 1.0)}, |
{PIPE_FORMAT_X8R8G8B8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0xffffffff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_A8B8G8R8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), UNPACKED_1x1(0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_A8B8G8R8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x000000ff), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_A8B8G8R8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x0000ff00), UNPACKED_1x1(0.0, 0.0, 1.0, 0.0)}, |
{PIPE_FORMAT_A8B8G8R8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00ff0000), UNPACKED_1x1(0.0, 1.0, 0.0, 0.0)}, |
{PIPE_FORMAT_A8B8G8R8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xff000000), UNPACKED_1x1(1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_A8B8G8R8_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xffffffff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_X8B8G8R8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0x00000000), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_X8B8G8R8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0x000000ff), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_X8B8G8R8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0x0000ff00), UNPACKED_1x1(0.0, 0.0, 1.0, 1.0)}, |
{PIPE_FORMAT_X8B8G8R8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0x00ff0000), UNPACKED_1x1(0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_X8B8G8R8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0xff000000), UNPACKED_1x1(1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_X8B8G8R8_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0xffffffff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8X8_UNORM, PACKED_1x32(0x00ffffff), PACKED_1x32(0x00000000), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8X8_UNORM, PACKED_1x32(0x00ffffff), PACKED_1x32(0x000000ff), UNPACKED_1x1(1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8X8_UNORM, PACKED_1x32(0x00ffffff), PACKED_1x32(0x0000ff00), UNPACKED_1x1(0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8X8_UNORM, PACKED_1x32(0x00ffffff), PACKED_1x32(0x00ff0000), UNPACKED_1x1(0.0, 0.0, 1.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8X8_UNORM, PACKED_1x32(0x00ffffff), PACKED_1x32(0xff000000), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8X8_UNORM, PACKED_1x32(0x00ffffff), PACKED_1x32(0xffffffff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_R10G10B10A2_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), UNPACKED_1x1(0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R10G10B10A2_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x000003ff), UNPACKED_1x1(1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R10G10B10A2_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x000ffc00), UNPACKED_1x1(0.0, 1.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R10G10B10A2_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x3ff00000), UNPACKED_1x1(0.0, 0.0, 1.0, 0.0)}, |
{PIPE_FORMAT_R10G10B10A2_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xc0000000), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R10G10B10A2_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xffffffff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_B10G10R10A2_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), UNPACKED_1x1(0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_B10G10R10A2_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x000003ff), UNPACKED_1x1(0.0, 0.0, 1.0, 0.0)}, |
{PIPE_FORMAT_B10G10R10A2_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x000ffc00), UNPACKED_1x1(0.0, 1.0, 0.0, 0.0)}, |
{PIPE_FORMAT_B10G10R10A2_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x3ff00000), UNPACKED_1x1(1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_B10G10R10A2_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xc0000000), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_B10G10R10A2_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xffffffff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
/* |
* 16-bit rendertarget formats |
*/ |
{PIPE_FORMAT_B5G5R5X1_UNORM, PACKED_1x16(0x7fff), PACKED_1x16(0x0000), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_B5G5R5X1_UNORM, PACKED_1x16(0x7fff), PACKED_1x16(0x001f), UNPACKED_1x1(0.0, 0.0, 1.0, 1.0)}, |
{PIPE_FORMAT_B5G5R5X1_UNORM, PACKED_1x16(0x7fff), PACKED_1x16(0x03e0), UNPACKED_1x1(0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_B5G5R5X1_UNORM, PACKED_1x16(0x7fff), PACKED_1x16(0x7c00), UNPACKED_1x1(1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_B5G5R5X1_UNORM, PACKED_1x16(0x7fff), PACKED_1x16(0x7fff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_B5G5R5A1_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x0000), UNPACKED_1x1(0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_B5G5R5A1_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x001f), UNPACKED_1x1(0.0, 0.0, 1.0, 0.0)}, |
{PIPE_FORMAT_B5G5R5A1_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x03e0), UNPACKED_1x1(0.0, 1.0, 0.0, 0.0)}, |
{PIPE_FORMAT_B5G5R5A1_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x7c00), UNPACKED_1x1(1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_B5G5R5A1_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x8000), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_B5G5R5A1_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0xffff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_B4G4R4X4_UNORM, PACKED_1x16(0x0fff), PACKED_1x16(0x0000), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_B4G4R4X4_UNORM, PACKED_1x16(0x0fff), PACKED_1x16(0x000f), UNPACKED_1x1(0.0, 0.0, 1.0, 1.0)}, |
{PIPE_FORMAT_B4G4R4X4_UNORM, PACKED_1x16(0x0fff), PACKED_1x16(0x00f0), UNPACKED_1x1(0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_B4G4R4X4_UNORM, PACKED_1x16(0x0fff), PACKED_1x16(0x0f00), UNPACKED_1x1(1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_B4G4R4X4_UNORM, PACKED_1x16(0x0fff), PACKED_1x16(0x0fff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_B4G4R4A4_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x0000), UNPACKED_1x1(0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_B4G4R4A4_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x000f), UNPACKED_1x1(0.0, 0.0, 1.0, 0.0)}, |
{PIPE_FORMAT_B4G4R4A4_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x00f0), UNPACKED_1x1(0.0, 1.0, 0.0, 0.0)}, |
{PIPE_FORMAT_B4G4R4A4_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x0f00), UNPACKED_1x1(1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_B4G4R4A4_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0xf000), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_B4G4R4A4_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0xffff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_B5G6R5_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x0000), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_B5G6R5_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x001f), UNPACKED_1x1(0.0, 0.0, 1.0, 1.0)}, |
{PIPE_FORMAT_B5G6R5_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x07e0), UNPACKED_1x1(0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_B5G6R5_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0xf800), UNPACKED_1x1(1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_B5G6R5_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0xffff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
/* |
* Luminance/intensity/alpha formats |
*/ |
{PIPE_FORMAT_L8_UNORM, PACKED_1x8(0xff), PACKED_1x8(0x00), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_L8_UNORM, PACKED_1x8(0xff), PACKED_1x8(0xff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_A8_UNORM, PACKED_1x8(0xff), PACKED_1x8(0x00), UNPACKED_1x1(0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_A8_UNORM, PACKED_1x8(0xff), PACKED_1x8(0xff), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_I8_UNORM, PACKED_1x8(0xff), PACKED_1x8(0x00), UNPACKED_1x1(0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_I8_UNORM, PACKED_1x8(0xff), PACKED_1x8(0xff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_L4A4_UNORM, PACKED_1x8(0xff), PACKED_1x8(0x00), UNPACKED_1x1(0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_L4A4_UNORM, PACKED_1x8(0xff), PACKED_1x8(0x0f), UNPACKED_1x1(1.0, 1.0, 1.0, 0.0)}, |
{PIPE_FORMAT_L4A4_UNORM, PACKED_1x8(0xff), PACKED_1x8(0xf0), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_L4A4_UNORM, PACKED_1x8(0xff), PACKED_1x8(0xff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_L8A8_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x0000), UNPACKED_1x1(0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_L8A8_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x00ff), UNPACKED_1x1(1.0, 1.0, 1.0, 0.0)}, |
{PIPE_FORMAT_L8A8_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0xff00), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_L8A8_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0xffff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_L16_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x0000), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_L16_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0xffff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
/* |
* SRGB formats |
*/ |
{PIPE_FORMAT_L8_SRGB, PACKED_1x8(0xff), PACKED_1x8(0x00), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_L8_SRGB, PACKED_1x8(0xff), PACKED_1x8(0xbc), UNPACKED_1x1(0.502886458033, 0.502886458033, 0.502886458033, 1.0)}, |
{PIPE_FORMAT_L8_SRGB, PACKED_1x8(0xff), PACKED_1x8(0xff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_L8A8_SRGB, PACKED_1x16(0xffff), PACKED_1x16(0x0000), UNPACKED_1x1(0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_L8A8_SRGB, PACKED_1x16(0xffff), PACKED_1x16(0x00bc), UNPACKED_1x1(0.502886458033, 0.502886458033, 0.502886458033, 0.0)}, |
{PIPE_FORMAT_L8A8_SRGB, PACKED_1x16(0xffff), PACKED_1x16(0x00ff), UNPACKED_1x1(1.0, 1.0, 1.0, 0.0)}, |
{PIPE_FORMAT_L8A8_SRGB, PACKED_1x16(0xffff), PACKED_1x16(0xcc00), UNPACKED_1x1(0.0, 0.0, 0.0, 0.8)}, |
{PIPE_FORMAT_L8A8_SRGB, PACKED_1x16(0xffff), PACKED_1x16(0xff00), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_L8A8_SRGB, PACKED_1x16(0xffff), PACKED_1x16(0xffff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_SRGB, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0x00), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_SRGB, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0xbc, 0x00, 0x00), UNPACKED_1x1(0.502886458033, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_SRGB, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0xff, 0x00, 0x00), UNPACKED_1x1(1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_SRGB, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0xbc, 0x00), UNPACKED_1x1(0.0, 0.502886458033, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_SRGB, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0xff, 0x00), UNPACKED_1x1(0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_SRGB, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0xbc), UNPACKED_1x1(0.0, 0.0, 0.502886458033, 1.0)}, |
{PIPE_FORMAT_R8G8B8_SRGB, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0xff), UNPACKED_1x1(0.0, 0.0, 1.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_SRGB, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0xff, 0xff, 0xff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8A8_SRGB, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0x00), UNPACKED_1x1(0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R8G8B8A8_SRGB, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0xbc, 0x00, 0x00, 0x00), UNPACKED_1x1(0.502886458033, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R8G8B8A8_SRGB, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0xff, 0x00, 0x00, 0x00), UNPACKED_1x1(1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R8G8B8A8_SRGB, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0xbc, 0x00, 0x00), UNPACKED_1x1(0.0, 0.502886458033, 0.0, 0.0)}, |
{PIPE_FORMAT_R8G8B8A8_SRGB, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0xff, 0x00, 0x00), UNPACKED_1x1(0.0, 1.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R8G8B8A8_SRGB, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0xbc, 0x00), UNPACKED_1x1(0.0, 0.0, 0.502886458033, 0.0)}, |
{PIPE_FORMAT_R8G8B8A8_SRGB, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0xff, 0x00), UNPACKED_1x1(0.0, 0.0, 1.0, 0.0)}, |
{PIPE_FORMAT_R8G8B8A8_SRGB, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0xcc), UNPACKED_1x1(0.0, 0.0, 0.0, 0.8)}, |
{PIPE_FORMAT_R8G8B8A8_SRGB, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0xff), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8A8_SRGB, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0xff, 0xff, 0xff, 0xff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_B8G8R8A8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), UNPACKED_1x1(0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_B8G8R8A8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0x000000bc), UNPACKED_1x1(0.0, 0.0, 0.502886458033, 0.0)}, |
{PIPE_FORMAT_B8G8R8A8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0x000000ff), UNPACKED_1x1(0.0, 0.0, 1.0, 0.0)}, |
{PIPE_FORMAT_B8G8R8A8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0x0000bc00), UNPACKED_1x1(0.0, 0.502886458033, 0.0, 0.0)}, |
{PIPE_FORMAT_B8G8R8A8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0x0000ff00), UNPACKED_1x1(0.0, 1.0, 0.0, 0.0)}, |
{PIPE_FORMAT_B8G8R8A8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0x00bc0000), UNPACKED_1x1(0.502886458033, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_B8G8R8A8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0x00ff0000), UNPACKED_1x1(1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_B8G8R8A8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0xcc000000), UNPACKED_1x1(0.0, 0.0, 0.0, 0.8)}, |
{PIPE_FORMAT_B8G8R8A8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0xff000000), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_B8G8R8A8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0xffffffff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_B8G8R8X8_SRGB, PACKED_1x32(0x00ffffff), PACKED_1x32(0x00000000), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_B8G8R8X8_SRGB, PACKED_1x32(0x00ffffff), PACKED_1x32(0x000000bc), UNPACKED_1x1(0.0, 0.0, 0.502886458033, 1.0)}, |
{PIPE_FORMAT_B8G8R8X8_SRGB, PACKED_1x32(0x00ffffff), PACKED_1x32(0x000000ff), UNPACKED_1x1(0.0, 0.0, 1.0, 1.0)}, |
{PIPE_FORMAT_B8G8R8X8_SRGB, PACKED_1x32(0x00ffffff), PACKED_1x32(0x0000bc00), UNPACKED_1x1(0.0, 0.502886458033, 0.0, 1.0)}, |
{PIPE_FORMAT_B8G8R8X8_SRGB, PACKED_1x32(0x00ffffff), PACKED_1x32(0x0000ff00), UNPACKED_1x1(0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_B8G8R8X8_SRGB, PACKED_1x32(0x00ffffff), PACKED_1x32(0x00bc0000), UNPACKED_1x1(0.502886458033, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_B8G8R8X8_SRGB, PACKED_1x32(0x00ffffff), PACKED_1x32(0x00ff0000), UNPACKED_1x1(1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_B8G8R8X8_SRGB, PACKED_1x32(0x00ffffff), PACKED_1x32(0xffffffff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_A8R8G8B8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), UNPACKED_1x1(0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_A8R8G8B8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0x000000cc), UNPACKED_1x1(0.0, 0.0, 0.0, 0.8)}, |
{PIPE_FORMAT_A8R8G8B8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0x000000ff), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_A8R8G8B8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0x0000bc00), UNPACKED_1x1(0.502886458033, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_A8R8G8B8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0x0000ff00), UNPACKED_1x1(1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_A8R8G8B8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0x00bc0000), UNPACKED_1x1(0.0, 0.502886458033, 0.0, 0.0)}, |
{PIPE_FORMAT_A8R8G8B8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0x00ff0000), UNPACKED_1x1(0.0, 1.0, 0.0, 0.0)}, |
{PIPE_FORMAT_A8R8G8B8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0xbc000000), UNPACKED_1x1(0.0, 0.0, 0.502886458033, 0.0)}, |
{PIPE_FORMAT_A8R8G8B8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0xff000000), UNPACKED_1x1(0.0, 0.0, 1.0, 0.0)}, |
{PIPE_FORMAT_A8R8G8B8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0xffffffff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_X8R8G8B8_SRGB, PACKED_1x32(0xffffff00), PACKED_1x32(0x00000000), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_X8R8G8B8_SRGB, PACKED_1x32(0xffffff00), PACKED_1x32(0x0000bc00), UNPACKED_1x1(0.502886458033, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_X8R8G8B8_SRGB, PACKED_1x32(0xffffff00), PACKED_1x32(0x0000ff00), UNPACKED_1x1(1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_X8R8G8B8_SRGB, PACKED_1x32(0xffffff00), PACKED_1x32(0x00bc0000), UNPACKED_1x1(0.0, 0.502886458033, 0.0, 1.0)}, |
{PIPE_FORMAT_X8R8G8B8_SRGB, PACKED_1x32(0xffffff00), PACKED_1x32(0x00ff0000), UNPACKED_1x1(0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_X8R8G8B8_SRGB, PACKED_1x32(0xffffff00), PACKED_1x32(0xbc000000), UNPACKED_1x1(0.0, 0.0, 0.502886458033, 1.0)}, |
{PIPE_FORMAT_X8R8G8B8_SRGB, PACKED_1x32(0xffffff00), PACKED_1x32(0xff000000), UNPACKED_1x1(0.0, 0.0, 1.0, 1.0)}, |
{PIPE_FORMAT_X8R8G8B8_SRGB, PACKED_1x32(0xffffff00), PACKED_1x32(0xffffffff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_A8B8G8R8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), UNPACKED_1x1(0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_A8B8G8R8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0x000000cc), UNPACKED_1x1(0.0, 0.0, 0.0, 0.8)}, |
{PIPE_FORMAT_A8B8G8R8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0x000000ff), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_A8B8G8R8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0x0000bc00), UNPACKED_1x1(0.0, 0.0, 0.502886458033, 0.0)}, |
{PIPE_FORMAT_A8B8G8R8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0x0000ff00), UNPACKED_1x1(0.0, 0.0, 1.0, 0.0)}, |
{PIPE_FORMAT_A8B8G8R8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0x00bc0000), UNPACKED_1x1(0.0, 0.502886458033, 0.0, 0.0)}, |
{PIPE_FORMAT_A8B8G8R8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0x00ff0000), UNPACKED_1x1(0.0, 1.0, 0.0, 0.0)}, |
{PIPE_FORMAT_A8B8G8R8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0xbc000000), UNPACKED_1x1(0.502886458033, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_A8B8G8R8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0xff000000), UNPACKED_1x1(1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_A8B8G8R8_SRGB, PACKED_1x32(0xffffffff), PACKED_1x32(0xffffffff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_X8B8G8R8_SRGB, PACKED_1x32(0xffffff00), PACKED_1x32(0x00000000), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_X8B8G8R8_SRGB, PACKED_1x32(0xffffff00), PACKED_1x32(0x0000bc00), UNPACKED_1x1(0.0, 0.0, 0.502886458033, 1.0)}, |
{PIPE_FORMAT_X8B8G8R8_SRGB, PACKED_1x32(0xffffff00), PACKED_1x32(0x0000ff00), UNPACKED_1x1(0.0, 0.0, 1.0, 1.0)}, |
{PIPE_FORMAT_X8B8G8R8_SRGB, PACKED_1x32(0xffffff00), PACKED_1x32(0x00bc0000), UNPACKED_1x1(0.0, 0.502886458033, 0.0, 1.0)}, |
{PIPE_FORMAT_X8B8G8R8_SRGB, PACKED_1x32(0xffffff00), PACKED_1x32(0x00ff0000), UNPACKED_1x1(0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_X8B8G8R8_SRGB, PACKED_1x32(0xffffff00), PACKED_1x32(0xbc000000), UNPACKED_1x1(0.502886458033, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_X8B8G8R8_SRGB, PACKED_1x32(0xffffff00), PACKED_1x32(0xff000000), UNPACKED_1x1(1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_X8B8G8R8_SRGB, PACKED_1x32(0xffffff00), PACKED_1x32(0xffffffff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
/* |
* Mixed-signed formats |
*/ |
{PIPE_FORMAT_R8SG8SB8UX8U_NORM, PACKED_4x8(0xff, 0xff, 0xff, 0x00), PACKED_4x8(0x00, 0x00, 0x00, 0x00), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8SG8SB8UX8U_NORM, PACKED_4x8(0xff, 0xff, 0xff, 0x00), PACKED_4x8(0x7f, 0x00, 0x00, 0x00), UNPACKED_1x1( 1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8SG8SB8UX8U_NORM, PACKED_4x8(0xff, 0xff, 0xff, 0x00), PACKED_4x8(0x81, 0x00, 0x00, 0x00), UNPACKED_1x1(-1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8SG8SB8UX8U_NORM, PACKED_4x8(0xff, 0xff, 0xff, 0x00), PACKED_4x8(0x00, 0x7f, 0x00, 0x00), UNPACKED_1x1( 0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8SG8SB8UX8U_NORM, PACKED_4x8(0xff, 0xff, 0xff, 0x00), PACKED_4x8(0x00, 0x81, 0x00, 0x00), UNPACKED_1x1( 0.0, -1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8SG8SB8UX8U_NORM, PACKED_4x8(0xff, 0xff, 0xff, 0x00), PACKED_4x8(0x00, 0x00, 0xff, 0x00), UNPACKED_1x1( 0.0, 0.0, 1.0, 1.0)}, |
{PIPE_FORMAT_R10SG10SB10SA2U_NORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R10SG10SB10SA2U_NORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x000001ff), UNPACKED_1x1( 1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R10SG10SB10SA2U_NORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000201), UNPACKED_1x1(-1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R10SG10SB10SA2U_NORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x0007fc00), UNPACKED_1x1( 0.0, 1.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R10SG10SB10SA2U_NORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00080400), UNPACKED_1x1( 0.0, -1.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R10SG10SB10SA2U_NORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x1ff00000), UNPACKED_1x1( 0.0, 0.0, 1.0, 0.0)}, |
{PIPE_FORMAT_R10SG10SB10SA2U_NORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x20100000), UNPACKED_1x1( 0.0, 0.0, -1.0, 0.0)}, |
{PIPE_FORMAT_R10SG10SB10SA2U_NORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xc0000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R5SG5SB6U_NORM, PACKED_1x16(0xffff), PACKED_1x16(0x0000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R5SG5SB6U_NORM, PACKED_1x16(0xffff), PACKED_1x16(0x000f), UNPACKED_1x1( 1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R5SG5SB6U_NORM, PACKED_1x16(0xffff), PACKED_1x16(0x0011), UNPACKED_1x1(-1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R5SG5SB6U_NORM, PACKED_1x16(0xffff), PACKED_1x16(0x01e0), UNPACKED_1x1( 0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R5SG5SB6U_NORM, PACKED_1x16(0xffff), PACKED_1x16(0x0220), UNPACKED_1x1( 0.0, -1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R5SG5SB6U_NORM, PACKED_1x16(0xffff), PACKED_1x16(0xfc00), UNPACKED_1x1( 0.0, 0.0, 1.0, 1.0)}, |
{PIPE_FORMAT_R8G8Bx_SNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0x00), UNPACKED_1x1( 0.0, 0.0, 1.0, 1.0)}, |
{PIPE_FORMAT_R8G8Bx_SNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x7f, 0x00), UNPACKED_1x1( 1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8Bx_SNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x81, 0x00), UNPACKED_1x1(-1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8Bx_SNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0x7f), UNPACKED_1x1( 0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8Bx_SNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0x81), UNPACKED_1x1( 0.0, -1.0, 0.0, 1.0)}, |
/* |
* Depth-stencil formats |
*/ |
{PIPE_FORMAT_S8_UINT, PACKED_1x8(0xff), PACKED_1x8(0x00), UNPACKED_1x1(0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_S8_UINT, PACKED_1x8(0xff), PACKED_1x8(0xff), UNPACKED_1x1(0.0, 255.0, 0.0, 0.0)}, |
{PIPE_FORMAT_Z16_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x0000), UNPACKED_1x1(0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_Z16_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0xffff), UNPACKED_1x1(1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_Z32_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), UNPACKED_1x1(0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_Z32_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xffffffff), UNPACKED_1x1(1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_Z32_FLOAT, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), UNPACKED_1x1(0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_Z32_FLOAT, PACKED_1x32(0xffffffff), PACKED_1x32(0x3f800000), UNPACKED_1x1(1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_Z24_UNORM_S8_UINT, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), UNPACKED_1x1(0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_Z24_UNORM_S8_UINT, PACKED_1x32(0xffffffff), PACKED_1x32(0x00ffffff), UNPACKED_1x1(1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_Z24_UNORM_S8_UINT, PACKED_1x32(0xffffffff), PACKED_1x32(0xff000000), UNPACKED_1x1(0.0, 255.0, 0.0, 0.0)}, |
{PIPE_FORMAT_Z24_UNORM_S8_UINT, PACKED_1x32(0xffffffff), PACKED_1x32(0xffffffff), UNPACKED_1x1(1.0, 255.0, 0.0, 0.0)}, |
{PIPE_FORMAT_S8_UINT_Z24_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), UNPACKED_1x1(0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_S8_UINT_Z24_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xffffff00), UNPACKED_1x1(1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_S8_UINT_Z24_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x000000ff), UNPACKED_1x1(0.0, 255.0, 0.0, 0.0)}, |
{PIPE_FORMAT_S8_UINT_Z24_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xffffffff), UNPACKED_1x1(1.0, 255.0, 0.0, 0.0)}, |
{PIPE_FORMAT_Z24X8_UNORM, PACKED_1x32(0x00ffffff), PACKED_1x32(0x00000000), UNPACKED_1x1(0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_Z24X8_UNORM, PACKED_1x32(0x00ffffff), PACKED_1x32(0x00ffffff), UNPACKED_1x1(1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_X8Z24_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0x00000000), UNPACKED_1x1(0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_X8Z24_UNORM, PACKED_1x32(0xffffff00), PACKED_1x32(0xffffff00), UNPACKED_1x1(1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_Z32_FLOAT_S8X24_UINT, PACKED_2x32(0xffffffff, 0x000000ff), PACKED_2x32(0x00000000, 0x00000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_Z32_FLOAT_S8X24_UINT, PACKED_2x32(0xffffffff, 0x000000ff), PACKED_2x32(0x3f800000, 0x00000000), UNPACKED_1x1( 1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_Z32_FLOAT_S8X24_UINT, PACKED_2x32(0xffffffff, 0x000000ff), PACKED_2x32(0x00000000, 0x000000ff), UNPACKED_1x1( 0.0, 255.0, 0.0, 0.0)}, |
/* |
* YUV formats |
*/ |
{PIPE_FORMAT_R8G8_B8G8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0x00), UNPACKED_2x1(0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8_B8G8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0xff, 0x00, 0x00, 0x00), UNPACKED_2x1(1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8_B8G8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0xff, 0x00, 0x00), UNPACKED_2x1(0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8_B8G8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0xff, 0x00), UNPACKED_2x1(0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0)}, |
{PIPE_FORMAT_R8G8_B8G8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0xff), UNPACKED_2x1(0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8_B8G8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0xff, 0xff, 0xff, 0xff), UNPACKED_2x1(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_G8R8_G8B8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0x00), UNPACKED_2x1(0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_G8R8_G8B8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0xff, 0x00, 0x00, 0x00), UNPACKED_2x1(0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_G8R8_G8B8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0xff, 0x00, 0x00), UNPACKED_2x1(1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_G8R8_G8B8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0xff, 0x00), UNPACKED_2x1(0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_G8R8_G8B8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0xff), UNPACKED_2x1(0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0)}, |
{PIPE_FORMAT_G8R8_G8B8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0xff, 0xff, 0xff, 0xff), UNPACKED_2x1(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0)}, |
/* |
* TODO: Exercise the UV channels as well. |
*/ |
{PIPE_FORMAT_UYVY, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x80, 0x10, 0x80, 0x10), UNPACKED_2x1(0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_UYVY, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x80, 0xeb, 0x80, 0x10), UNPACKED_2x1(1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_UYVY, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x80, 0x10, 0x80, 0xeb), UNPACKED_2x1(0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_YUYV, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x10, 0x80, 0x10, 0x80), UNPACKED_2x1(0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_YUYV, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0xeb, 0x80, 0x10, 0x80), UNPACKED_2x1(1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_YUYV, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x10, 0x80, 0xeb, 0x80), UNPACKED_2x1(0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0)}, |
/* |
* Compressed formats |
*/ |
{ |
PIPE_FORMAT_DXT1_RGB, |
PACKED_8x8(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff), |
PACKED_8x8(0xf2, 0xd7, 0xb0, 0x20, 0xae, 0x2c, 0x6f, 0x97), |
{ |
{ |
{0x99/255.0, 0xb0/255.0, 0x8e/255.0, 0xff/255.0}, |
{0x5d/255.0, 0x62/255.0, 0x89/255.0, 0xff/255.0}, |
{0x99/255.0, 0xb0/255.0, 0x8e/255.0, 0xff/255.0}, |
{0x99/255.0, 0xb0/255.0, 0x8e/255.0, 0xff/255.0} |
}, |
{ |
{0xd6/255.0, 0xff/255.0, 0x94/255.0, 0xff/255.0}, |
{0x5d/255.0, 0x62/255.0, 0x89/255.0, 0xff/255.0}, |
{0x99/255.0, 0xb0/255.0, 0x8e/255.0, 0xff/255.0}, |
{0xd6/255.0, 0xff/255.0, 0x94/255.0, 0xff/255.0} |
}, |
{ |
{0x5d/255.0, 0x62/255.0, 0x89/255.0, 0xff/255.0}, |
{0x5d/255.0, 0x62/255.0, 0x89/255.0, 0xff/255.0}, |
{0x99/255.0, 0xb0/255.0, 0x8e/255.0, 0xff/255.0}, |
{0x21/255.0, 0x14/255.0, 0x84/255.0, 0xff/255.0} |
}, |
{ |
{0x5d/255.0, 0x62/255.0, 0x89/255.0, 0xff/255.0}, |
{0x21/255.0, 0x14/255.0, 0x84/255.0, 0xff/255.0}, |
{0x21/255.0, 0x14/255.0, 0x84/255.0, 0xff/255.0}, |
{0x99/255.0, 0xb0/255.0, 0x8e/255.0, 0xff/255.0} |
} |
} |
}, |
{ |
PIPE_FORMAT_DXT1_RGBA, |
PACKED_8x8(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff), |
PACKED_8x8(0xff, 0x2f, 0xa4, 0x72, 0xeb, 0xb2, 0xbd, 0xbe), |
{ |
{ |
{0x00/255.0, 0x00/255.0, 0x00/255.0, 0x00/255.0}, |
{0x4e/255.0, 0xaa/255.0, 0x90/255.0, 0xff/255.0}, |
{0x4e/255.0, 0xaa/255.0, 0x90/255.0, 0xff/255.0}, |
{0x00/255.0, 0x00/255.0, 0x00/255.0, 0x00/255.0} |
}, |
{ |
{0x4e/255.0, 0xaa/255.0, 0x90/255.0, 0xff/255.0}, |
{0x29/255.0, 0xff/255.0, 0xff/255.0, 0xff/255.0}, |
{0x00/255.0, 0x00/255.0, 0x00/255.0, 0x00/255.0}, |
{0x4e/255.0, 0xaa/255.0, 0x90/255.0, 0xff/255.0} |
}, |
{ |
{0x73/255.0, 0x55/255.0, 0x21/255.0, 0xff/255.0}, |
{0x00/255.0, 0x00/255.0, 0x00/255.0, 0x00/255.0}, |
{0x00/255.0, 0x00/255.0, 0x00/255.0, 0x00/255.0}, |
{0x4e/255.0, 0xaa/255.0, 0x90/255.0, 0xff/255.0} |
}, |
{ |
{0x4e/255.0, 0xaa/255.0, 0x90/255.0, 0xff/255.0}, |
{0x00/255.0, 0x00/255.0, 0x00/255.0, 0x00/255.0}, |
{0x00/255.0, 0x00/255.0, 0x00/255.0, 0x00/255.0}, |
{0x4e/255.0, 0xaa/255.0, 0x90/255.0, 0xff/255.0} |
} |
} |
}, |
{ |
PIPE_FORMAT_DXT3_RGBA, |
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, |
{0xe7, 0x4a, 0x8f, 0x96, 0x5b, 0xc1, 0x1c, 0x84, 0xf6, 0x8f, 0xab, 0x32, 0x2a, 0x9a, 0x95, 0x5a}, |
{ |
{ |
{0x6d/255.0, 0xc6/255.0, 0x96/255.0, 0x77/255.0}, |
{0x6d/255.0, 0xc6/255.0, 0x96/255.0, 0xee/255.0}, |
{0x6d/255.0, 0xc6/255.0, 0x96/255.0, 0xaa/255.0}, |
{0x8c/255.0, 0xff/255.0, 0xb5/255.0, 0x44/255.0} |
}, |
{ |
{0x6d/255.0, 0xc6/255.0, 0x96/255.0, 0xff/255.0}, |
{0x6d/255.0, 0xc6/255.0, 0x96/255.0, 0x88/255.0}, |
{0x31/255.0, 0x55/255.0, 0x5a/255.0, 0x66/255.0}, |
{0x6d/255.0, 0xc6/255.0, 0x96/255.0, 0x99/255.0} |
}, |
{ |
{0x31/255.0, 0x55/255.0, 0x5a/255.0, 0xbb/255.0}, |
{0x31/255.0, 0x55/255.0, 0x5a/255.0, 0x55/255.0}, |
{0x31/255.0, 0x55/255.0, 0x5a/255.0, 0x11/255.0}, |
{0x6d/255.0, 0xc6/255.0, 0x96/255.0, 0xcc/255.0} |
}, |
{ |
{0x6d/255.0, 0xc6/255.0, 0x96/255.0, 0xcc/255.0}, |
{0x6d/255.0, 0xc6/255.0, 0x96/255.0, 0x11/255.0}, |
{0x31/255.0, 0x55/255.0, 0x5a/255.0, 0x44/255.0}, |
{0x31/255.0, 0x55/255.0, 0x5a/255.0, 0x88/255.0} |
} |
} |
}, |
{ |
PIPE_FORMAT_DXT5_RGBA, |
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, |
{0xf8, 0x11, 0xc5, 0x0c, 0x9a, 0x73, 0xb4, 0x9c, 0xf6, 0x8f, 0xab, 0x32, 0x2a, 0x9a, 0x95, 0x5a}, |
{ |
{ |
{0x6d/255.0, 0xc6/255.0, 0x96/255.0, 0x74/255.0}, |
{0x6d/255.0, 0xc6/255.0, 0x96/255.0, 0xf8/255.0}, |
{0x6d/255.0, 0xc6/255.0, 0x96/255.0, 0xb6/255.0}, |
{0x8c/255.0, 0xff/255.0, 0xb5/255.0, 0x53/255.0} |
}, |
{ |
{0x6d/255.0, 0xc6/255.0, 0x96/255.0, 0xf8/255.0}, |
{0x6d/255.0, 0xc6/255.0, 0x96/255.0, 0x95/255.0}, |
{0x31/255.0, 0x55/255.0, 0x5a/255.0, 0x53/255.0}, |
{0x6d/255.0, 0xc6/255.0, 0x96/255.0, 0x95/255.0} |
}, |
{ |
{0x31/255.0, 0x55/255.0, 0x5a/255.0, 0xb6/255.0}, |
{0x31/255.0, 0x55/255.0, 0x5a/255.0, 0x53/255.0}, |
{0x31/255.0, 0x55/255.0, 0x5a/255.0, 0x11/255.0}, |
{0x6d/255.0, 0xc6/255.0, 0x96/255.0, 0xd7/255.0} |
}, |
{ |
{0x6d/255.0, 0xc6/255.0, 0x96/255.0, 0xb6/255.0}, |
{0x6d/255.0, 0xc6/255.0, 0x96/255.0, 0x11/255.0}, |
{0x31/255.0, 0x55/255.0, 0x5a/255.0, 0x32/255.0}, |
{0x31/255.0, 0x55/255.0, 0x5a/255.0, 0x95/255.0} |
} |
} |
}, |
/* |
* Standard 8-bit integer formats |
*/ |
{PIPE_FORMAT_R8_UNORM, PACKED_1x8(0xff), PACKED_1x8(0x00), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8_UNORM, PACKED_1x8(0xff), PACKED_1x8(0xff), UNPACKED_1x1(1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8_UNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0x00), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8_UNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0xff, 0x00), UNPACKED_1x1(1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8_UNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0xff), UNPACKED_1x1(0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8_UNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0xff, 0xff), UNPACKED_1x1(1.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_UNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0x00), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_UNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0xff, 0x00, 0x00), UNPACKED_1x1(1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_UNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0xff, 0x00), UNPACKED_1x1(0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_UNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0xff), UNPACKED_1x1(0.0, 0.0, 1.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_UNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0xff, 0xff, 0xff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8A8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0x00), UNPACKED_1x1(0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R8G8B8A8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0xff, 0x00, 0x00, 0x00), UNPACKED_1x1(1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R8G8B8A8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0xff, 0x00, 0x00), UNPACKED_1x1(0.0, 1.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R8G8B8A8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0xff, 0x00), UNPACKED_1x1(0.0, 0.0, 1.0, 0.0)}, |
{PIPE_FORMAT_R8G8B8A8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0xff), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8A8_UNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0xff, 0xff, 0xff, 0xff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_R8_USCALED, PACKED_1x8(0xff), PACKED_1x8(0x00), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8_USCALED, PACKED_1x8(0xff), PACKED_1x8(0xff), UNPACKED_1x1(255.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8_USCALED, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0x00), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8_USCALED, PACKED_2x8(0xff, 0xff), PACKED_2x8(0xff, 0x00), UNPACKED_1x1(255.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8_USCALED, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0xff), UNPACKED_1x1( 0.0, 255.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8_USCALED, PACKED_2x8(0xff, 0xff), PACKED_2x8(0xff, 0xff), UNPACKED_1x1(255.0, 255.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_USCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0x00), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_USCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0xff, 0x00, 0x00), UNPACKED_1x1(255.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_USCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0xff, 0x00), UNPACKED_1x1( 0.0, 255.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_USCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0xff), UNPACKED_1x1( 0.0, 0.0, 255.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_USCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0xff, 0xff, 0xff), UNPACKED_1x1(255.0, 255.0, 255.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8A8_USCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0x00), UNPACKED_1x1( 0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R8G8B8A8_USCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0xff, 0x00, 0x00, 0x00), UNPACKED_1x1(255.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R8G8B8A8_USCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0xff, 0x00, 0x00), UNPACKED_1x1( 0.0, 255.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R8G8B8A8_USCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0xff, 0x00), UNPACKED_1x1( 0.0, 0.0, 255.0, 0.0)}, |
{PIPE_FORMAT_R8G8B8A8_USCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0xff), UNPACKED_1x1( 0.0, 0.0, 0.0, 255.0)}, |
{PIPE_FORMAT_R8G8B8A8_USCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0xff, 0xff, 0xff, 0xff), UNPACKED_1x1(255.0, 255.0, 255.0, 255.0)}, |
{PIPE_FORMAT_R8_SNORM, PACKED_1x8(0xff), PACKED_1x8(0x00), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8_SNORM, PACKED_1x8(0xff), PACKED_1x8(0x7f), UNPACKED_1x1( 1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8_SNORM, PACKED_1x8(0xff), PACKED_1x8(0x81), UNPACKED_1x1(-1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8_SNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0x00), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8_SNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x7f, 0x00), UNPACKED_1x1( 1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8_SNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x81, 0x00), UNPACKED_1x1(-1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8_SNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0x7f), UNPACKED_1x1( 0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8_SNORM, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0x81), UNPACKED_1x1( 0.0, -1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_SNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0x00), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_SNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x7f, 0x00, 0x00), UNPACKED_1x1( 1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_SNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x81, 0x00, 0x00), UNPACKED_1x1(-1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_SNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x7f, 0x00), UNPACKED_1x1( 0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_SNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x81, 0x00), UNPACKED_1x1( 0.0, -1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_SNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0x7f), UNPACKED_1x1( 0.0, 0.0, 1.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_SNORM, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0x81), UNPACKED_1x1( 0.0, 0.0, -1.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8A8_SNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0x00), UNPACKED_1x1( 0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R8G8B8A8_SNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x7f, 0x00, 0x00, 0x00), UNPACKED_1x1( 1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R8G8B8A8_SNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x81, 0x00, 0x00, 0x00), UNPACKED_1x1(-1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R8G8B8A8_SNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x7f, 0x00, 0x00), UNPACKED_1x1( 0.0, 1.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R8G8B8A8_SNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x81, 0x00, 0x00), UNPACKED_1x1( 0.0, -1.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R8G8B8A8_SNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x7f, 0x00), UNPACKED_1x1( 0.0, 0.0, 1.0, 0.0)}, |
{PIPE_FORMAT_R8G8B8A8_SNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x81, 0x00), UNPACKED_1x1( 0.0, 0.0, -1.0, 0.0)}, |
{PIPE_FORMAT_R8G8B8A8_SNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0x7f), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8A8_SNORM, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0x81), UNPACKED_1x1( 0.0, 0.0, 0.0, -1.0)}, |
{PIPE_FORMAT_R8_SSCALED, PACKED_1x8(0xff), PACKED_1x8(0x00), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8_SSCALED, PACKED_1x8(0xff), PACKED_1x8(0x7f), UNPACKED_1x1( 127.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8_SSCALED, PACKED_1x8(0xff), PACKED_1x8(0x80), UNPACKED_1x1(-128.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8_SSCALED, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0x00), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8_SSCALED, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x7f, 0x00), UNPACKED_1x1( 127.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8_SSCALED, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x80, 0x00), UNPACKED_1x1(-128.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8_SSCALED, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0x7f), UNPACKED_1x1( 0.0, 127.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8_SSCALED, PACKED_2x8(0xff, 0xff), PACKED_2x8(0x00, 0x80), UNPACKED_1x1( 0.0, -128.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_SSCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0x00), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_SSCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x7f, 0x00, 0x00), UNPACKED_1x1( 127.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_SSCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x80, 0x00, 0x00), UNPACKED_1x1(-128.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_SSCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x7f, 0x00), UNPACKED_1x1( 0.0, 127.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_SSCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x80, 0x00), UNPACKED_1x1( 0.0, -128.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_SSCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0x7f), UNPACKED_1x1( 0.0, 0.0, 127.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8_SSCALED, PACKED_3x8(0xff, 0xff, 0xff), PACKED_3x8(0x00, 0x00, 0x80), UNPACKED_1x1( 0.0, 0.0, -128.0, 1.0)}, |
{PIPE_FORMAT_R8G8B8A8_SSCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0x00), UNPACKED_1x1( 0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R8G8B8A8_SSCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x7f, 0x00, 0x00, 0x00), UNPACKED_1x1( 127.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R8G8B8A8_SSCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x80, 0x00, 0x00, 0x00), UNPACKED_1x1(-128.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R8G8B8A8_SSCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x7f, 0x00, 0x00), UNPACKED_1x1( 0.0, 127.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R8G8B8A8_SSCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x80, 0x00, 0x00), UNPACKED_1x1( 0.0, -128.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R8G8B8A8_SSCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x7f, 0x00), UNPACKED_1x1( 0.0, 0.0, 127.0, 0.0)}, |
{PIPE_FORMAT_R8G8B8A8_SSCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x80, 0x00), UNPACKED_1x1( 0.0, 0.0, -128.0, 0.0)}, |
{PIPE_FORMAT_R8G8B8A8_SSCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0x7f), UNPACKED_1x1( 0.0, 0.0, 0.0, 127.0)}, |
{PIPE_FORMAT_R8G8B8A8_SSCALED, PACKED_4x8(0xff, 0xff, 0xff, 0xff), PACKED_4x8(0x00, 0x00, 0x00, 0x80), UNPACKED_1x1( 0.0, 0.0, 0.0, -128.0)}, |
/* |
* Standard 16-bit integer formats |
*/ |
{PIPE_FORMAT_R16_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0x0000), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16_UNORM, PACKED_1x16(0xffff), PACKED_1x16(0xffff), UNPACKED_1x1(1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16_UNORM, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0x0000), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16_UNORM, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0xffff, 0x0000), UNPACKED_1x1(1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16_UNORM, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0xffff), UNPACKED_1x1(0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16_UNORM, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0xffff, 0xffff), UNPACKED_1x1(1.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_UNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0x0000), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_UNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0xffff, 0x0000, 0x0000), UNPACKED_1x1(1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_UNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0xffff, 0x0000), UNPACKED_1x1(0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_UNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0xffff), UNPACKED_1x1(0.0, 0.0, 1.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_UNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0xffff, 0xffff, 0xffff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16A16_UNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0x0000), UNPACKED_1x1(0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R16G16B16A16_UNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0xffff, 0x0000, 0x0000, 0x0000), UNPACKED_1x1(1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R16G16B16A16_UNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0xffff, 0x0000, 0x0000), UNPACKED_1x1(0.0, 1.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R16G16B16A16_UNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0xffff, 0x0000), UNPACKED_1x1(0.0, 0.0, 1.0, 0.0)}, |
{PIPE_FORMAT_R16G16B16A16_UNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0xffff), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16A16_UNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_R16_USCALED, PACKED_1x16(0xffff), PACKED_1x16(0x0000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16_USCALED, PACKED_1x16(0xffff), PACKED_1x16(0xffff), UNPACKED_1x1(65535.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16_USCALED, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0x0000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16_USCALED, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0xffff, 0x0000), UNPACKED_1x1(65535.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16_USCALED, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0xffff), UNPACKED_1x1( 0.0, 65535.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16_USCALED, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0xffff, 0xffff), UNPACKED_1x1(65535.0, 65535.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_USCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0x0000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_USCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0xffff, 0x0000, 0x0000), UNPACKED_1x1(65535.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_USCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0xffff, 0x0000), UNPACKED_1x1( 0.0, 65535.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_USCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0xffff), UNPACKED_1x1( 0.0, 0.0, 65535.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_USCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0xffff, 0xffff, 0xffff), UNPACKED_1x1(65535.0, 65535.0, 65535.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16A16_USCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0x0000), UNPACKED_1x1( 0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R16G16B16A16_USCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0xffff, 0x0000, 0x0000, 0x0000), UNPACKED_1x1(65535.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R16G16B16A16_USCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0xffff, 0x0000, 0x0000), UNPACKED_1x1( 0.0, 65535.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R16G16B16A16_USCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0xffff, 0x0000), UNPACKED_1x1( 0.0, 0.0, 65535.0, 0.0)}, |
{PIPE_FORMAT_R16G16B16A16_USCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0xffff), UNPACKED_1x1( 0.0, 0.0, 0.0, 65535.0)}, |
{PIPE_FORMAT_R16G16B16A16_USCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), UNPACKED_1x1(65535.0, 65535.0, 65535.0, 65535.0)}, |
{PIPE_FORMAT_R16_SNORM, PACKED_1x16(0xffff), PACKED_1x16(0x0000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16_SNORM, PACKED_1x16(0xffff), PACKED_1x16(0x7fff), UNPACKED_1x1( 1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16_SNORM, PACKED_1x16(0xffff), PACKED_1x16(0x8001), UNPACKED_1x1( -1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16_SNORM, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0x0000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16_SNORM, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x7fff, 0x0000), UNPACKED_1x1( 1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16_SNORM, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x8001, 0x0000), UNPACKED_1x1( -1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16_SNORM, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0x7fff), UNPACKED_1x1( 0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16_SNORM, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0x8001), UNPACKED_1x1( 0.0, -1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_SNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0x0000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_SNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x7fff, 0x0000, 0x0000), UNPACKED_1x1( 1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_SNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x8001, 0x0000, 0x0000), UNPACKED_1x1( -1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_SNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x7fff, 0x0000), UNPACKED_1x1( 0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_SNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x8001, 0x0000), UNPACKED_1x1( 0.0, -1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_SNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0x7fff), UNPACKED_1x1( 0.0, 0.0, 1.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_SNORM, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0x8001), UNPACKED_1x1( 0.0, 0.0, -1.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16A16_SNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0x0000), UNPACKED_1x1( 0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R16G16B16A16_SNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x7fff, 0x0000, 0x0000, 0x0000), UNPACKED_1x1( 1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R16G16B16A16_SNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x8001, 0x0000, 0x0000, 0x0000), UNPACKED_1x1( -1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R16G16B16A16_SNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x7fff, 0x0000, 0x0000), UNPACKED_1x1( 0.0, 1.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R16G16B16A16_SNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x8001, 0x0000, 0x0000), UNPACKED_1x1( 0.0, -1.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R16G16B16A16_SNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x7fff, 0x0000), UNPACKED_1x1( 0.0, 0.0, 1.0, 0.0)}, |
{PIPE_FORMAT_R16G16B16A16_SNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x8001, 0x0000), UNPACKED_1x1( 0.0, 0.0, -1.0, 0.0)}, |
{PIPE_FORMAT_R16G16B16A16_SNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0x7fff), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16A16_SNORM, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0x8001), UNPACKED_1x1( 0.0, 0.0, 0.0, -1.0)}, |
{PIPE_FORMAT_R16_SSCALED, PACKED_1x16(0xffff), PACKED_1x16(0x0000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16_SSCALED, PACKED_1x16(0xffff), PACKED_1x16(0x7fff), UNPACKED_1x1( 32767.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16_SSCALED, PACKED_1x16(0xffff), PACKED_1x16(0x8000), UNPACKED_1x1(-32768.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16_SSCALED, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0x0000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16_SSCALED, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x7fff, 0x0000), UNPACKED_1x1( 32767.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16_SSCALED, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x8000, 0x0000), UNPACKED_1x1(-32768.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16_SSCALED, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0x7fff), UNPACKED_1x1( 0.0, 32767.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16_SSCALED, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0x8000), UNPACKED_1x1( 0.0, -32768.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_SSCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0x0000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_SSCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x7fff, 0x0000, 0x0000), UNPACKED_1x1( 32767.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_SSCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x8000, 0x0000, 0x0000), UNPACKED_1x1(-32768.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_SSCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x7fff, 0x0000), UNPACKED_1x1( 0.0, 32767.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_SSCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x8000, 0x0000), UNPACKED_1x1( 0.0, -32768.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_SSCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0x7fff), UNPACKED_1x1( 0.0, 0.0, 32767.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_SSCALED, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0x8000), UNPACKED_1x1( 0.0, 0.0, -32768.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16A16_SSCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0x0000), UNPACKED_1x1( 0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R16G16B16A16_SSCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x7fff, 0x0000, 0x0000, 0x0000), UNPACKED_1x1( 32767.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R16G16B16A16_SSCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x8000, 0x0000, 0x0000, 0x0000), UNPACKED_1x1(-32768.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R16G16B16A16_SSCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x7fff, 0x0000, 0x0000), UNPACKED_1x1( 0.0, 32767.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R16G16B16A16_SSCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x8000, 0x0000, 0x0000), UNPACKED_1x1( 0.0, -32768.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R16G16B16A16_SSCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x7fff, 0x0000), UNPACKED_1x1( 0.0, 0.0, 32767.0, 0.0)}, |
{PIPE_FORMAT_R16G16B16A16_SSCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x8000, 0x0000), UNPACKED_1x1( 0.0, 0.0, -32768.0, 0.0)}, |
{PIPE_FORMAT_R16G16B16A16_SSCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0x7fff), UNPACKED_1x1( 0.0, 0.0, 0.0, 32767.0)}, |
{PIPE_FORMAT_R16G16B16A16_SSCALED, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0x8000), UNPACKED_1x1( 0.0, 0.0, 0.0, -32768.0)}, |
/* |
* Standard 32-bit integer formats |
* |
* NOTE: We can't accurately represent integers larger than +/-0x1000000 |
* with single precision floats, so that's as far as we test. |
*/ |
{PIPE_FORMAT_R32_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32_UNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0xffffffff), UNPACKED_1x1(1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_UNORM, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x00000000), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_UNORM, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0xffffffff, 0x00000000), UNPACKED_1x1(1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_UNORM, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0xffffffff), UNPACKED_1x1(0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_UNORM, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0xffffffff, 0xffffffff), UNPACKED_1x1(1.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_UNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x00000000), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_UNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0xffffffff, 0x00000000, 0x00000000), UNPACKED_1x1(1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_UNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0xffffffff, 0x00000000), UNPACKED_1x1(0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_UNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0xffffffff), UNPACKED_1x1(0.0, 0.0, 1.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_UNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32A32_UNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x00000000), UNPACKED_1x1(0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_UNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0xffffffff, 0x00000000, 0x00000000, 0x00000000), UNPACKED_1x1(1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_UNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0xffffffff, 0x00000000, 0x00000000), UNPACKED_1x1(0.0, 1.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_UNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0xffffffff, 0x00000000), UNPACKED_1x1(0.0, 0.0, 1.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_UNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0xffffffff), UNPACKED_1x1(0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32A32_UNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), UNPACKED_1x1(1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_R32_USCALED, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32_USCALED, PACKED_1x32(0xffffffff), PACKED_1x32(0x01000000), UNPACKED_1x1(16777216.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_USCALED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x00000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_USCALED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x01000000, 0x00000000), UNPACKED_1x1(16777216.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_USCALED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x01000000), UNPACKED_1x1( 0.0, 16777216.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_USCALED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x01000000, 0x01000000), UNPACKED_1x1(16777216.0, 16777216.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_USCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x00000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_USCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x01000000, 0x00000000, 0x00000000), UNPACKED_1x1(16777216.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_USCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x01000000, 0x00000000), UNPACKED_1x1( 0.0, 16777216.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_USCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x01000000), UNPACKED_1x1( 0.0, 0.0, 16777216.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_USCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x01000000, 0x01000000, 0x01000000), UNPACKED_1x1(16777216.0, 16777216.0, 16777216.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32A32_USCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x00000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_USCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x01000000, 0x00000000, 0x00000000, 0x00000000), UNPACKED_1x1(16777216.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_USCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x01000000, 0x00000000, 0x00000000), UNPACKED_1x1( 0.0, 16777216.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_USCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x01000000, 0x00000000), UNPACKED_1x1( 0.0, 0.0, 16777216.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_USCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x01000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 16777216.0)}, |
{PIPE_FORMAT_R32G32B32A32_USCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x01000000, 0x01000000, 0x01000000, 0x01000000), UNPACKED_1x1(16777216.0, 16777216.0, 16777216.0, 16777216.0)}, |
{PIPE_FORMAT_R32_SNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32_SNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x7fffffff), UNPACKED_1x1( 1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32_SNORM, PACKED_1x32(0xffffffff), PACKED_1x32(0x80000001), UNPACKED_1x1( -1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_SNORM, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x00000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_SNORM, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x7fffffff, 0x00000000), UNPACKED_1x1( 1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_SNORM, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x80000001, 0x00000000), UNPACKED_1x1( -1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_SNORM, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x7fffffff), UNPACKED_1x1( 0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_SNORM, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x80000001), UNPACKED_1x1( 0.0, -1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_SNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x00000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_SNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x7fffffff, 0x00000000, 0x00000000), UNPACKED_1x1( 1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_SNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x80000001, 0x00000000, 0x00000000), UNPACKED_1x1( -1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_SNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x7fffffff, 0x00000000), UNPACKED_1x1( 0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_SNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x80000001, 0x00000000), UNPACKED_1x1( 0.0, -1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_SNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x7fffffff), UNPACKED_1x1( 0.0, 0.0, 1.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_SNORM, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x80000001), UNPACKED_1x1( 0.0, 0.0, -1.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32A32_SNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x00000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_SNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x7fffffff, 0x00000000, 0x00000000, 0x00000000), UNPACKED_1x1( 1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_SNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x80000001, 0x00000000, 0x00000000, 0x00000000), UNPACKED_1x1( -1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_SNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x7fffffff, 0x00000000, 0x00000000), UNPACKED_1x1( 0.0, 1.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_SNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x80000001, 0x00000000, 0x00000000), UNPACKED_1x1( 0.0, -1.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_SNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x7fffffff, 0x00000000), UNPACKED_1x1( 0.0, 0.0, 1.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_SNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x80000001, 0x00000000), UNPACKED_1x1( 0.0, 0.0, -1.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_SNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x7fffffff), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32A32_SNORM, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x80000001), UNPACKED_1x1( 0.0, 0.0, 0.0, -1.0)}, |
{PIPE_FORMAT_R32_SSCALED, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32_SSCALED, PACKED_1x32(0xffffffff), PACKED_1x32(0x01000000), UNPACKED_1x1( 16777216.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32_SSCALED, PACKED_1x32(0xffffffff), PACKED_1x32(0xff000000), UNPACKED_1x1(-16777216.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_SSCALED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x00000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_SSCALED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x01000000, 0x00000000), UNPACKED_1x1( 16777216.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_SSCALED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0xff000000, 0x00000000), UNPACKED_1x1(-16777216.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_SSCALED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x01000000), UNPACKED_1x1( 0.0, 16777216.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_SSCALED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0xff000000), UNPACKED_1x1( 0.0, -16777216.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_SSCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x00000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_SSCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x01000000, 0x00000000, 0x00000000), UNPACKED_1x1( 16777216.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_SSCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0xff000000, 0x00000000, 0x00000000), UNPACKED_1x1(-16777216.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_SSCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x01000000, 0x00000000), UNPACKED_1x1( 0.0, 16777216.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_SSCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0xff000000, 0x00000000), UNPACKED_1x1( 0.0, -16777216.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_SSCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x01000000), UNPACKED_1x1( 0.0, 0.0, 16777216.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_SSCALED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0xff000000), UNPACKED_1x1( 0.0, 0.0, -16777216.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32A32_SSCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x00000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_SSCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x01000000, 0x00000000, 0x00000000, 0x00000000), UNPACKED_1x1( 16777216.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_SSCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0xff000000, 0x00000000, 0x00000000, 0x00000000), UNPACKED_1x1(-16777216.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_SSCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x01000000, 0x00000000, 0x00000000), UNPACKED_1x1( 0.0, 16777216.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_SSCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0xff000000, 0x00000000, 0x00000000), UNPACKED_1x1( 0.0, -16777216.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_SSCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x01000000, 0x00000000), UNPACKED_1x1( 0.0, 0.0, 16777216.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_SSCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0xff000000, 0x00000000), UNPACKED_1x1( 0.0, 0.0, -16777216.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_SSCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x01000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 16777216.0)}, |
{PIPE_FORMAT_R32G32B32A32_SSCALED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0xff000000), UNPACKED_1x1( 0.0, 0.0, 0.0, -16777216.0)}, |
/* |
* Standard 32-bit float formats |
*/ |
{PIPE_FORMAT_R32_FLOAT, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32_FLOAT, PACKED_1x32(0xffffffff), PACKED_1x32(0x3f800000), UNPACKED_1x1( 1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32_FLOAT, PACKED_1x32(0xffffffff), PACKED_1x32(0xbf800000), UNPACKED_1x1( -1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_FLOAT, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x00000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_FLOAT, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x3f800000, 0x00000000), UNPACKED_1x1( 1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_FLOAT, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0xbf800000, 0x00000000), UNPACKED_1x1(-1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_FLOAT, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x3f800000), UNPACKED_1x1( 0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_FLOAT, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0xbf800000), UNPACKED_1x1( 0.0, -1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_FLOAT, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x3f800000, 0x3f800000), UNPACKED_1x1( 1.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_FLOAT, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x00000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_FLOAT, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x3f800000, 0x00000000, 0x00000000), UNPACKED_1x1( 1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_FLOAT, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0xbf800000, 0x00000000, 0x00000000), UNPACKED_1x1(-1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_FLOAT, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x3f800000, 0x00000000), UNPACKED_1x1( 0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_FLOAT, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0xbf800000, 0x00000000), UNPACKED_1x1( 0.0, -1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_FLOAT, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x3f800000), UNPACKED_1x1( 0.0, 0.0, 1.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_FLOAT, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0xbf800000), UNPACKED_1x1( 0.0, 0.0, -1.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_FLOAT, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x3f800000, 0x3f800000, 0x3f800000), UNPACKED_1x1( 1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x00000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x3f800000, 0x00000000, 0x00000000, 0x00000000), UNPACKED_1x1( 1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0xbf800000, 0x00000000, 0x00000000, 0x00000000), UNPACKED_1x1(-1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x3f800000, 0x00000000, 0x00000000), UNPACKED_1x1( 0.0, 1.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0xbf800000, 0x00000000, 0x00000000), UNPACKED_1x1( 0.0, -1.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x3f800000, 0x00000000), UNPACKED_1x1( 0.0, 0.0, 1.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0xbf800000, 0x00000000), UNPACKED_1x1( 0.0, 0.0, -1.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x3f800000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0xbf800000), UNPACKED_1x1( 0.0, 0.0, 0.0, -1.0)}, |
{PIPE_FORMAT_R32G32B32A32_FLOAT, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x3f800000, 0x3f800000, 0x3f800000, 0x3f800000), UNPACKED_1x1( 1.0, 1.0, 1.0, 1.0)}, |
/* |
* Half float formats |
*/ |
/* Minimum positive normal */ |
{PIPE_FORMAT_R16_FLOAT, PACKED_1x16(0xffff), PACKED_1x16(0x0400), UNPACKED_1x1( 6.10352E-5, 0.0, 0.0, 1.0)}, |
/* XXX: Now that we disable denormals this test cases fails, except on |
* IvyBridge processors which have intrinsics dedicated to half-float |
* packing/unpacking. */ |
#if 0 |
/* Max denormal */ |
{PIPE_FORMAT_R16_FLOAT, PACKED_1x16(0xffff), PACKED_1x16(0x03FF), UNPACKED_1x1( 6.09756E-5, 0.0, 0.0, 1.0)}, |
#endif |
/* Minimum positive denormal */ |
{PIPE_FORMAT_R16_FLOAT, PACKED_1x16(0xffff), PACKED_1x16(0x0001), UNPACKED_1x1( 5.96046E-8, 0.0, 0.0, 1.0)}, |
/* Min representable value */ |
{PIPE_FORMAT_R16_FLOAT, PACKED_1x16(0xffff), PACKED_1x16(0xfbff), UNPACKED_1x1( -65504.0, 0.0, 0.0, 1.0)}, |
/* Max representable value */ |
{PIPE_FORMAT_R16_FLOAT, PACKED_1x16(0xffff), PACKED_1x16(0x7bff), UNPACKED_1x1( 65504.0, 0.0, 0.0, 1.0)}, |
#if !defined(PIPE_CC_MSVC) |
/* NaNs */ |
{PIPE_FORMAT_R16_FLOAT, PACKED_1x16(0xffff), PACKED_1x16(0x7c01), UNPACKED_1x1( NAN, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16_FLOAT, PACKED_1x16(0xffff), PACKED_1x16(0xfc01), UNPACKED_1x1( -NAN, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16_FLOAT, PACKED_1x16(0xffff), PACKED_1x16(0x7fff), UNPACKED_1x1( NAN, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16_FLOAT, PACKED_1x16(0xffff), PACKED_1x16(0xffff), UNPACKED_1x1( -NAN, 0.0, 0.0, 1.0)}, |
/* Inf */ |
{PIPE_FORMAT_R16_FLOAT, PACKED_1x16(0xffff), PACKED_1x16(0x7c00), UNPACKED_1x1( INFINITY, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16_FLOAT, PACKED_1x16(0xffff), PACKED_1x16(0xfc00), UNPACKED_1x1( -INFINITY, 0.0, 0.0, 1.0)}, |
#endif |
/* Zero, ignore sign */ |
{PIPE_FORMAT_R16_FLOAT, PACKED_1x16(0x7fff), PACKED_1x16(0x8000), UNPACKED_1x1( -0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16_FLOAT, PACKED_1x16(0x7fff), PACKED_1x16(0x0000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16_FLOAT, PACKED_1x16(0xffff), PACKED_1x16(0x3c00), UNPACKED_1x1( 1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16_FLOAT, PACKED_1x16(0xffff), PACKED_1x16(0xbc00), UNPACKED_1x1( -1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16_FLOAT, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0x0000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16_FLOAT, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x3c00, 0x0000), UNPACKED_1x1( 1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16_FLOAT, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0xbc00, 0x0000), UNPACKED_1x1(-1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16_FLOAT, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0x3c00), UNPACKED_1x1( 0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16_FLOAT, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x0000, 0xbc00), UNPACKED_1x1( 0.0, -1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16_FLOAT, PACKED_2x16(0xffff, 0xffff), PACKED_2x16(0x3c00, 0x3c00), UNPACKED_1x1( 1.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_FLOAT, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0x0000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_FLOAT, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x3c00, 0x0000, 0x0000), UNPACKED_1x1( 1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_FLOAT, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0xbc00, 0x0000, 0x0000), UNPACKED_1x1(-1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_FLOAT, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x3c00, 0x0000), UNPACKED_1x1( 0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_FLOAT, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0xbc00, 0x0000), UNPACKED_1x1( 0.0, -1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_FLOAT, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0x3c00), UNPACKED_1x1( 0.0, 0.0, 1.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_FLOAT, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x0000, 0x0000, 0xbc00), UNPACKED_1x1( 0.0, 0.0, -1.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16_FLOAT, PACKED_3x16(0xffff, 0xffff, 0xffff), PACKED_3x16(0x3c00, 0x3c00, 0x3c00), UNPACKED_1x1( 1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16A16_FLOAT, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0x0000), UNPACKED_1x1( 0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R16G16B16A16_FLOAT, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x3c00, 0x0000, 0x0000, 0x0000), UNPACKED_1x1( 1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R16G16B16A16_FLOAT, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0xbc00, 0x0000, 0x0000, 0x0000), UNPACKED_1x1(-1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R16G16B16A16_FLOAT, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x3c00, 0x0000, 0x0000), UNPACKED_1x1( 0.0, 1.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R16G16B16A16_FLOAT, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0xbc00, 0x0000, 0x0000), UNPACKED_1x1( 0.0, -1.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R16G16B16A16_FLOAT, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x3c00, 0x0000), UNPACKED_1x1( 0.0, 0.0, 1.0, 0.0)}, |
{PIPE_FORMAT_R16G16B16A16_FLOAT, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0xbc00, 0x0000), UNPACKED_1x1( 0.0, 0.0, -1.0, 0.0)}, |
{PIPE_FORMAT_R16G16B16A16_FLOAT, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0x3c00), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R16G16B16A16_FLOAT, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x0000, 0x0000, 0x0000, 0xbc00), UNPACKED_1x1( 0.0, 0.0, 0.0, -1.0)}, |
{PIPE_FORMAT_R16G16B16A16_FLOAT, PACKED_4x16(0xffff, 0xffff, 0xffff, 0xffff), PACKED_4x16(0x3c00, 0x3c00, 0x3c00, 0x3c00), UNPACKED_1x1( 1.0, 1.0, 1.0, 1.0)}, |
/* |
* 32-bit fixed point formats |
*/ |
{PIPE_FORMAT_R32_FIXED, PACKED_1x32(0xffffffff), PACKED_1x32(0x00000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32_FIXED, PACKED_1x32(0xffffffff), PACKED_1x32(0x00010000), UNPACKED_1x1( 1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32_FIXED, PACKED_1x32(0xffffffff), PACKED_1x32(0xffff0000), UNPACKED_1x1( -1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_FIXED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x00000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_FIXED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00010000, 0x00000000), UNPACKED_1x1( 1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_FIXED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0xffff0000, 0x00000000), UNPACKED_1x1(-1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_FIXED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0x00010000), UNPACKED_1x1( 0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_FIXED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00000000, 0xffff0000), UNPACKED_1x1( 0.0, -1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32_FIXED, PACKED_2x32(0xffffffff, 0xffffffff), PACKED_2x32(0x00010000, 0x00010000), UNPACKED_1x1( 1.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_FIXED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x00000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_FIXED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00010000, 0x00000000, 0x00000000), UNPACKED_1x1( 1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_FIXED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0xffff0000, 0x00000000, 0x00000000), UNPACKED_1x1(-1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_FIXED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00010000, 0x00000000), UNPACKED_1x1( 0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_FIXED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0xffff0000, 0x00000000), UNPACKED_1x1( 0.0, -1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_FIXED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0x00010000), UNPACKED_1x1( 0.0, 0.0, 1.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_FIXED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00000000, 0x00000000, 0xffff0000), UNPACKED_1x1( 0.0, 0.0, -1.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32_FIXED, PACKED_3x32(0xffffffff, 0xffffffff, 0xffffffff), PACKED_3x32(0x00010000, 0x00010000, 0x00010000), UNPACKED_1x1( 1.0, 1.0, 1.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32A32_FIXED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x00000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_FIXED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00010000, 0x00000000, 0x00000000, 0x00000000), UNPACKED_1x1( 1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_FIXED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0xffff0000, 0x00000000, 0x00000000, 0x00000000), UNPACKED_1x1(-1.0, 0.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_FIXED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00010000, 0x00000000, 0x00000000), UNPACKED_1x1( 0.0, 1.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_FIXED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0xffff0000, 0x00000000, 0x00000000), UNPACKED_1x1( 0.0, -1.0, 0.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_FIXED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00010000, 0x00000000), UNPACKED_1x1( 0.0, 0.0, 1.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_FIXED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0xffff0000, 0x00000000), UNPACKED_1x1( 0.0, 0.0, -1.0, 0.0)}, |
{PIPE_FORMAT_R32G32B32A32_FIXED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0x00010000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R32G32B32A32_FIXED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00000000, 0x00000000, 0x00000000, 0xffff0000), UNPACKED_1x1( 0.0, 0.0, 0.0, -1.0)}, |
{PIPE_FORMAT_R32G32B32A32_FIXED, PACKED_4x32(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff), PACKED_4x32(0x00010000, 0x00010000, 0x00010000, 0x00010000), UNPACKED_1x1( 1.0, 1.0, 1.0, 1.0)}, |
/* |
* D3D9 specific vertex formats |
*/ |
{PIPE_FORMAT_R10G10B10X2_USCALED, PACKED_1x32(0x3fffffff), PACKED_1x32(0x00000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R10G10B10X2_USCALED, PACKED_1x32(0x3fffffff), PACKED_1x32(0x000003ff), UNPACKED_1x1(1023.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R10G10B10X2_USCALED, PACKED_1x32(0x3fffffff), PACKED_1x32(0x000ffc00), UNPACKED_1x1( 0.0, 1023.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R10G10B10X2_USCALED, PACKED_1x32(0x3fffffff), PACKED_1x32(0x3ff00000), UNPACKED_1x1( 0.0, 0.0, 1023.0, 1.0)}, |
{PIPE_FORMAT_R10G10B10X2_USCALED, PACKED_1x32(0x3fffffff), PACKED_1x32(0x3fffffff), UNPACKED_1x1(1023.0, 1023.0, 1023.0, 1.0)}, |
{PIPE_FORMAT_R10G10B10X2_SNORM, PACKED_1x32(0x3fffffff), PACKED_1x32(0x00000000), UNPACKED_1x1( 0.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R10G10B10X2_SNORM, PACKED_1x32(0x3fffffff), PACKED_1x32(0x000001ff), UNPACKED_1x1( 1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R10G10B10X2_SNORM, PACKED_1x32(0x3fffffff), PACKED_1x32(0x00000201), UNPACKED_1x1(-1.0, 0.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R10G10B10X2_SNORM, PACKED_1x32(0x3fffffff), PACKED_1x32(0x0007fc00), UNPACKED_1x1( 0.0, 1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R10G10B10X2_SNORM, PACKED_1x32(0x3fffffff), PACKED_1x32(0x00080400), UNPACKED_1x1( 0.0, -1.0, 0.0, 1.0)}, |
{PIPE_FORMAT_R10G10B10X2_SNORM, PACKED_1x32(0x3fffffff), PACKED_1x32(0x1ff00000), UNPACKED_1x1( 0.0, 0.0, 1.0, 1.0)}, |
{PIPE_FORMAT_R10G10B10X2_SNORM, PACKED_1x32(0x3fffffff), PACKED_1x32(0x20100000), UNPACKED_1x1( 0.0, 0.0, -1.0, 1.0)}, |
/* |
* Special formats that not fit anywhere else |
*/ |
}; |
const unsigned util_format_nr_test_cases = Elements(util_format_test_cases); |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_format_tests.h |
---|
0,0 → 1,71 |
/************************************************************************** |
* |
* Copyright 2010 VMware, Inc. |
* 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 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 |
* THE COPYRIGHT HOLDERS, 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. |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
**************************************************************************/ |
#ifndef U_FORMAT_TESTS_H_ |
#define U_FORMAT_TESTS_H_ |
#include "pipe/p_compiler.h" |
#include "pipe/p_format.h" |
#define UTIL_FORMAT_MAX_PACKED_BYTES 16 |
#define UTIL_FORMAT_MAX_UNPACKED_WIDTH 4 |
#define UTIL_FORMAT_MAX_UNPACKED_HEIGHT 4 |
/** |
* A (packed, unpacked) color pair. |
*/ |
struct util_format_test_case |
{ |
enum pipe_format format; |
/** |
* Mask of the bits that actually meaningful data. Used to mask out the |
* "X" channels. |
*/ |
uint8_t mask[UTIL_FORMAT_MAX_PACKED_BYTES]; |
uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES]; |
/** |
* RGBA. |
*/ |
double unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4]; |
}; |
extern const struct util_format_test_case |
util_format_test_cases[]; |
extern const unsigned util_format_nr_test_cases; |
#endif /* U_FORMAT_TESTS_H_ */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_format_yuv.c |
---|
0,0 → 1,1193 |
/************************************************************************** |
* |
* Copyright 2010 VMware, Inc. |
* 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 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 |
* THE COPYRIGHT HOLDERS, 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. |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
**************************************************************************/ |
/** |
* @file |
* YUV and RGB subsampled formats conversion. |
* |
* @author Jose Fonseca <jfonseca@vmware.com> |
*/ |
#include "util/u_debug.h" |
#include "util/u_format_yuv.h" |
void |
util_format_r8g8_b8g8_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for (y = 0; y < height; y += 1) { |
float *dst = dst_row; |
const uint32_t *src = (const uint32_t *)src_row; |
uint32_t value; |
float r, g0, g1, b; |
for (x = 0; x + 1 < width; x += 2) { |
value = *src++; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
r = ubyte_to_float((value >> 0) & 0xff); |
g0 = ubyte_to_float((value >> 8) & 0xff); |
b = ubyte_to_float((value >> 16) & 0xff); |
g1 = ubyte_to_float((value >> 24) & 0xff); |
dst[0] = r; /* r */ |
dst[1] = g0; /* g */ |
dst[2] = b; /* b */ |
dst[3] = 1.0f; /* a */ |
dst += 4; |
dst[0] = r; /* r */ |
dst[1] = g1; /* g */ |
dst[2] = b; /* b */ |
dst[3] = 1.0f; /* a */ |
dst += 4; |
} |
if (x < width) { |
value = *src; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
r = ubyte_to_float((value >> 0) & 0xff); |
g0 = ubyte_to_float((value >> 8) & 0xff); |
b = ubyte_to_float((value >> 16) & 0xff); |
g1 = ubyte_to_float((value >> 24) & 0xff); |
dst[0] = r; /* r */ |
dst[1] = g0; /* g */ |
dst[2] = b; /* b */ |
dst[3] = 1.0f; /* a */ |
} |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_r8g8_b8g8_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for (y = 0; y < height; y += 1) { |
uint8_t *dst = dst_row; |
const uint32_t *src = (const uint32_t *)src_row; |
uint32_t value; |
uint8_t r, g0, g1, b; |
for (x = 0; x + 1 < width; x += 2) { |
value = *src++; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
r = (value >> 0) & 0xff; |
g0 = (value >> 8) & 0xff; |
b = (value >> 16) & 0xff; |
g1 = (value >> 24) & 0xff; |
dst[0] = r; /* r */ |
dst[1] = g0; /* g */ |
dst[2] = b; /* b */ |
dst[3] = 0xff; /* a */ |
dst += 4; |
dst[0] = r; /* r */ |
dst[1] = g1; /* g */ |
dst[2] = b; /* b */ |
dst[3] = 0xff; /* a */ |
dst += 4; |
} |
if (x < width) { |
value = *src; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
r = (value >> 0) & 0xff; |
g0 = (value >> 8) & 0xff; |
b = (value >> 16) & 0xff; |
g1 = (value >> 24) & 0xff; |
dst[0] = r; /* r */ |
dst[1] = g0; /* g */ |
dst[2] = b; /* b */ |
dst[3] = 0xff; /* a */ |
} |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_r8g8_b8g8_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for (y = 0; y < height; y += 1) { |
const float *src = src_row; |
uint32_t *dst = (uint32_t *)dst_row; |
float r, g0, g1, b; |
uint32_t value; |
for (x = 0; x + 1 < width; x += 2) { |
r = 0.5f*(src[0] + src[4]); |
g0 = src[1]; |
g1 = src[5]; |
b = 0.5f*(src[2] + src[6]); |
value = float_to_ubyte(r); |
value |= float_to_ubyte(g0) << 8; |
value |= float_to_ubyte(b) << 16; |
value |= float_to_ubyte(g1) << 24; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = value; |
src += 8; |
} |
if (x < width) { |
r = src[0]; |
g0 = src[1]; |
g1 = 0; |
b = src[2]; |
value = float_to_ubyte(r); |
value |= float_to_ubyte(g0) << 8; |
value |= float_to_ubyte(b) << 16; |
value |= float_to_ubyte(g1) << 24; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst = value; |
} |
dst_row += dst_stride/sizeof(*dst_row); |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_r8g8_b8g8_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for (y = 0; y < height; y += 1) { |
const uint8_t *src = src_row; |
uint32_t *dst = (uint32_t *)dst_row; |
uint32_t r, g0, g1, b; |
uint32_t value; |
for (x = 0; x + 1 < width; x += 2) { |
r = (src[0] + src[4] + 1) >> 1; |
g0 = src[1]; |
g1 = src[5]; |
b = (src[2] + src[6] + 1) >> 1; |
value = r; |
value |= g0 << 8; |
value |= b << 16; |
value |= g1 << 24; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = value; |
src += 8; |
} |
if (x < width) { |
r = src[0]; |
g0 = src[1]; |
g1 = 0; |
b = src[2]; |
value = r; |
value |= g0 << 8; |
value |= b << 16; |
value |= g1 << 24; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst = value; |
} |
dst_row += dst_stride/sizeof(*dst_row); |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_r8g8_b8g8_unorm_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j) |
{ |
assert(i < 2); |
assert(j < 1); |
dst[0] = ubyte_to_float(src[0]); /* r */ |
dst[1] = ubyte_to_float(src[1 + 2*i]); /* g */ |
dst[2] = ubyte_to_float(src[2]); /* b */ |
dst[3] = 1.0f; /* a */ |
} |
void |
util_format_g8r8_g8b8_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for (y = 0; y < height; y += 1) { |
float *dst = dst_row; |
const uint32_t *src = (const uint32_t *)src_row; |
uint32_t value; |
float r, g0, g1, b; |
for (x = 0; x + 1 < width; x += 2) { |
value = *src++; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
g0 = ubyte_to_float((value >> 0) & 0xff); |
r = ubyte_to_float((value >> 8) & 0xff); |
g1 = ubyte_to_float((value >> 16) & 0xff); |
b = ubyte_to_float((value >> 24) & 0xff); |
dst[0] = r; /* r */ |
dst[1] = g0; /* g */ |
dst[2] = b; /* b */ |
dst[3] = 1.0f; /* a */ |
dst += 4; |
dst[0] = r; /* r */ |
dst[1] = g1; /* g */ |
dst[2] = b; /* b */ |
dst[3] = 1.0f; /* a */ |
dst += 4; |
} |
if (x < width) { |
value = *src; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
g0 = ubyte_to_float((value >> 0) & 0xff); |
r = ubyte_to_float((value >> 8) & 0xff); |
g1 = ubyte_to_float((value >> 16) & 0xff); |
b = ubyte_to_float((value >> 24) & 0xff); |
dst[0] = r; /* r */ |
dst[1] = g0; /* g */ |
dst[2] = b; /* b */ |
dst[3] = 1.0f; /* a */ |
} |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_g8r8_g8b8_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for (y = 0; y < height; y += 1) { |
uint8_t *dst = dst_row; |
const uint32_t *src = (const uint32_t *)src_row; |
uint32_t value; |
uint8_t r, g0, g1, b; |
for (x = 0; x + 1 < width; x += 2) { |
value = *src++; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
g0 = (value >> 0) & 0xff; |
r = (value >> 8) & 0xff; |
g1 = (value >> 16) & 0xff; |
b = (value >> 24) & 0xff; |
dst[0] = r; /* r */ |
dst[1] = g0; /* g */ |
dst[2] = b; /* b */ |
dst[3] = 0xff; /* a */ |
dst += 4; |
dst[0] = r; /* r */ |
dst[1] = g1; /* g */ |
dst[2] = b; /* b */ |
dst[3] = 0xff; /* a */ |
dst += 4; |
} |
if (x < width) { |
value = *src; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
g0 = (value >> 0) & 0xff; |
r = (value >> 8) & 0xff; |
g1 = (value >> 16) & 0xff; |
b = (value >> 24) & 0xff; |
dst[0] = r; /* r */ |
dst[1] = g0; /* g */ |
dst[2] = b; /* b */ |
dst[3] = 0xff; /* a */ |
} |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_g8r8_g8b8_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for (y = 0; y < height; y += 1) { |
const float *src = src_row; |
uint32_t *dst = (uint32_t *)dst_row; |
float r, g0, g1, b; |
uint32_t value; |
for (x = 0; x + 1 < width; x += 2) { |
r = 0.5f*(src[0] + src[4]); |
g0 = src[1]; |
g1 = src[5]; |
b = 0.5f*(src[2] + src[6]); |
value = float_to_ubyte(g0); |
value |= float_to_ubyte(r) << 8; |
value |= float_to_ubyte(g1) << 16; |
value |= float_to_ubyte(b) << 24; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = value; |
src += 8; |
} |
if (x < width) { |
r = src[0]; |
g0 = src[1]; |
g1 = 0; |
b = src[2]; |
value = float_to_ubyte(g0); |
value |= float_to_ubyte(r) << 8; |
value |= float_to_ubyte(g1) << 16; |
value |= float_to_ubyte(b) << 24; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst = value; |
} |
dst_row += dst_stride/sizeof(*dst_row); |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_g8r8_g8b8_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for (y = 0; y < height; y += 1) { |
const uint8_t *src = src_row; |
uint32_t *dst = (uint32_t *)dst_row; |
uint32_t r, g0, g1, b; |
uint32_t value; |
for (x = 0; x + 1 < width; x += 2) { |
r = (src[0] + src[4] + 1) >> 1; |
g0 = src[1]; |
g1 = src[5]; |
b = (src[2] + src[6] + 1) >> 1; |
value = g0; |
value |= r << 8; |
value |= g1 << 16; |
value |= b << 24; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = value; |
src += 8; |
} |
if (x < width) { |
r = src[0]; |
g0 = src[1]; |
g1 = 0; |
b = src[2]; |
value = g0; |
value |= r << 8; |
value |= g1 << 16; |
value |= b << 24; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst = value; |
} |
dst_row += dst_stride/sizeof(*dst_row); |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_g8r8_g8b8_unorm_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j) |
{ |
assert(i < 2); |
assert(j < 1); |
dst[0] = ubyte_to_float(src[1]); /* r */ |
dst[1] = ubyte_to_float(src[0 + 2*i]); /* g */ |
dst[2] = ubyte_to_float(src[3]); /* b */ |
dst[3] = 1.0f; /* a */ |
} |
void |
util_format_uyvy_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for (y = 0; y < height; y += 1) { |
float *dst = dst_row; |
const uint32_t *src = (const uint32_t *)src_row; |
uint32_t value; |
uint8_t y0, y1, u, v; |
for (x = 0; x + 1 < width; x += 2) { |
value = *src++; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
u = (value >> 0) & 0xff; |
y0 = (value >> 8) & 0xff; |
v = (value >> 16) & 0xff; |
y1 = (value >> 24) & 0xff; |
util_format_yuv_to_rgb_float(y0, u, v, &dst[0], &dst[1], &dst[2]); |
dst[3] = 1.0f; /* a */ |
dst += 4; |
util_format_yuv_to_rgb_float(y1, u, v, &dst[0], &dst[1], &dst[2]); |
dst[3] = 1.0f; /* a */ |
dst += 4; |
} |
if (x < width) { |
value = *src; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
u = (value >> 0) & 0xff; |
y0 = (value >> 8) & 0xff; |
v = (value >> 16) & 0xff; |
y1 = (value >> 24) & 0xff; |
util_format_yuv_to_rgb_float(y0, u, v, &dst[0], &dst[1], &dst[2]); |
dst[3] = 1.0f; /* a */ |
} |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_uyvy_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for (y = 0; y < height; y += 1) { |
uint8_t *dst = dst_row; |
const uint32_t *src = (const uint32_t *)src_row; |
uint32_t value; |
uint8_t y0, y1, u, v; |
for (x = 0; x + 1 < width; x += 2) { |
value = *src++; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
u = (value >> 0) & 0xff; |
y0 = (value >> 8) & 0xff; |
v = (value >> 16) & 0xff; |
y1 = (value >> 24) & 0xff; |
util_format_yuv_to_rgb_8unorm(y0, u, v, &dst[0], &dst[1], &dst[2]); |
dst[3] = 0xff; /* a */ |
dst += 4; |
util_format_yuv_to_rgb_8unorm(y1, u, v, &dst[0], &dst[1], &dst[2]); |
dst[3] = 0xff; /* a */ |
dst += 4; |
} |
if (x < width) { |
value = *src; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
u = (value >> 0) & 0xff; |
y0 = (value >> 8) & 0xff; |
v = (value >> 16) & 0xff; |
y1 = (value >> 24) & 0xff; |
util_format_yuv_to_rgb_8unorm(y0, u, v, &dst[0], &dst[1], &dst[2]); |
dst[3] = 0xff; /* a */ |
} |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_uyvy_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for (y = 0; y < height; y += 1) { |
const float *src = src_row; |
uint32_t *dst = (uint32_t *)dst_row; |
uint8_t y0, y1, u, v; |
uint32_t value; |
for (x = 0; x + 1 < width; x += 2) { |
uint8_t y0, y1, u0, u1, v0, v1, u, v; |
util_format_rgb_float_to_yuv(src[0], src[1], src[2], |
&y0, &u0, &v0); |
util_format_rgb_float_to_yuv(src[4], src[5], src[6], |
&y1, &u1, &v1); |
u = (u0 + u1 + 1) >> 1; |
v = (v0 + v1 + 1) >> 1; |
value = u; |
value |= y0 << 8; |
value |= v << 16; |
value |= y1 << 24; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = value; |
src += 8; |
} |
if (x < width) { |
util_format_rgb_float_to_yuv(src[0], src[1], src[2], |
&y0, &u, &v); |
y1 = 0; |
value = u; |
value |= y0 << 8; |
value |= v << 16; |
value |= y1 << 24; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst = value; |
} |
dst_row += dst_stride/sizeof(*dst_row); |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_uyvy_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for (y = 0; y < height; y += 1) { |
const uint8_t *src = src_row; |
uint32_t *dst = (uint32_t *)dst_row; |
uint8_t y0, y1, u, v; |
uint32_t value; |
for (x = 0; x + 1 < width; x += 2) { |
uint8_t y0, y1, u0, u1, v0, v1, u, v; |
util_format_rgb_8unorm_to_yuv(src[0], src[1], src[2], |
&y0, &u0, &v0); |
util_format_rgb_8unorm_to_yuv(src[4], src[5], src[6], |
&y1, &u1, &v1); |
u = (u0 + u1 + 1) >> 1; |
v = (v0 + v1 + 1) >> 1; |
value = u; |
value |= y0 << 8; |
value |= v << 16; |
value |= y1 << 24; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = value; |
src += 8; |
} |
if (x < width) { |
util_format_rgb_8unorm_to_yuv(src[0], src[1], src[2], |
&y0, &u, &v); |
y1 = 0; |
value = u; |
value |= y0 << 8; |
value |= v << 16; |
value |= y1 << 24; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst = value; |
} |
dst_row += dst_stride/sizeof(*dst_row); |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_uyvy_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j) |
{ |
uint8_t y, u, v; |
assert(i < 2); |
assert(j < 1); |
y = src[1 + i*2]; |
u = src[0]; |
v = src[2]; |
util_format_yuv_to_rgb_float(y, u, v, &dst[0], &dst[1], &dst[2]); |
dst[3] = 1.0f; |
} |
void |
util_format_yuyv_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for (y = 0; y < height; y += 1) { |
float *dst = dst_row; |
const uint32_t *src = (const uint32_t *)src_row; |
uint32_t value; |
uint8_t y0, y1, u, v; |
for (x = 0; x + 1 < width; x += 2) { |
value = *src++; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
y0 = (value >> 0) & 0xff; |
u = (value >> 8) & 0xff; |
y1 = (value >> 16) & 0xff; |
v = (value >> 24) & 0xff; |
util_format_yuv_to_rgb_float(y0, u, v, &dst[0], &dst[1], &dst[2]); |
dst[3] = 1.0f; /* a */ |
dst += 4; |
util_format_yuv_to_rgb_float(y1, u, v, &dst[0], &dst[1], &dst[2]); |
dst[3] = 1.0f; /* a */ |
dst += 4; |
} |
if (x < width) { |
value = *src; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
y0 = (value >> 0) & 0xff; |
u = (value >> 8) & 0xff; |
y1 = (value >> 16) & 0xff; |
v = (value >> 24) & 0xff; |
util_format_yuv_to_rgb_float(y0, u, v, &dst[0], &dst[1], &dst[2]); |
dst[3] = 1.0f; /* a */ |
} |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_yuyv_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for (y = 0; y < height; y += 1) { |
uint8_t *dst = dst_row; |
const uint32_t *src = (const uint32_t *)src_row; |
uint32_t value; |
uint8_t y0, y1, u, v; |
for (x = 0; x + 1 < width; x += 2) { |
value = *src++; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
y0 = (value >> 0) & 0xff; |
u = (value >> 8) & 0xff; |
y1 = (value >> 16) & 0xff; |
v = (value >> 24) & 0xff; |
util_format_yuv_to_rgb_8unorm(y0, u, v, &dst[0], &dst[1], &dst[2]); |
dst[3] = 0xff; /* a */ |
dst += 4; |
util_format_yuv_to_rgb_8unorm(y1, u, v, &dst[0], &dst[1], &dst[2]); |
dst[3] = 0xff; /* a */ |
dst += 4; |
} |
if (x < width) { |
value = *src; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
y0 = (value >> 0) & 0xff; |
u = (value >> 8) & 0xff; |
y1 = (value >> 16) & 0xff; |
v = (value >> 24) & 0xff; |
util_format_yuv_to_rgb_8unorm(y0, u, v, &dst[0], &dst[1], &dst[2]); |
dst[3] = 0xff; /* a */ |
} |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_yuyv_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for (y = 0; y < height; y += 1) { |
const float *src = src_row; |
uint32_t *dst = (uint32_t *)dst_row; |
uint8_t y0, y1, u, v; |
uint32_t value; |
for (x = 0; x + 1 < width; x += 2) { |
uint8_t y0, y1, u0, u1, v0, v1, u, v; |
util_format_rgb_float_to_yuv(src[0], src[1], src[2], |
&y0, &u0, &v0); |
util_format_rgb_float_to_yuv(src[4], src[5], src[6], |
&y1, &u1, &v1); |
u = (u0 + u1 + 1) >> 1; |
v = (v0 + v1 + 1) >> 1; |
value = y0; |
value |= u << 8; |
value |= y1 << 16; |
value |= v << 24; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = value; |
src += 8; |
} |
if (x < width) { |
util_format_rgb_float_to_yuv(src[0], src[1], src[2], |
&y0, &u, &v); |
y1 = 0; |
value = y0; |
value |= u << 8; |
value |= y1 << 16; |
value |= v << 24; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst = value; |
} |
dst_row += dst_stride/sizeof(*dst_row); |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_yuyv_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for (y = 0; y < height; y += 1) { |
const uint8_t *src = src_row; |
uint32_t *dst = (uint32_t *)dst_row; |
uint8_t y0, y1, u, v; |
uint32_t value; |
for (x = 0; x + 1 < width; x += 2) { |
uint8_t y0, y1, u0, u1, v0, v1, u, v; |
util_format_rgb_8unorm_to_yuv(src[0], src[1], src[2], |
&y0, &u0, &v0); |
util_format_rgb_8unorm_to_yuv(src[4], src[5], src[6], |
&y1, &u1, &v1); |
u = (u0 + u1 + 1) >> 1; |
v = (v0 + v1 + 1) >> 1; |
value = y0; |
value |= u << 8; |
value |= y1 << 16; |
value |= v << 24; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = value; |
src += 8; |
} |
if (x < width) { |
util_format_rgb_8unorm_to_yuv(src[0], src[1], src[2], |
&y0, &u, &v); |
y1 = 0; |
value = y0; |
value |= u << 8; |
value |= y1 << 16; |
value |= v << 24; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst = value; |
} |
dst_row += dst_stride/sizeof(*dst_row); |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_yuyv_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j) |
{ |
uint8_t y, u, v; |
assert(i < 2); |
assert(j < 1); |
y = src[0 + i*2]; |
u = src[1]; |
v = src[3]; |
util_format_yuv_to_rgb_float(y, u, v, &dst[0], &dst[1], &dst[2]); |
dst[3] = 1.0f; |
} |
/* XXX: Stubbed for now */ |
void |
util_format_yv12_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) {} |
void |
util_format_yv12_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) {} |
void |
util_format_yv12_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) {} |
void |
util_format_yv12_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height) {} |
void |
util_format_yv12_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j) {} |
void |
util_format_yv16_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) {} |
void |
util_format_yv16_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) {} |
void |
util_format_yv16_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) {} |
void |
util_format_yv16_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height) {} |
void |
util_format_yv16_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j) {} |
void |
util_format_iyuv_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) {} |
void |
util_format_iyuv_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) {} |
void |
util_format_iyuv_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) {} |
void |
util_format_iyuv_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height) {} |
void |
util_format_iyuv_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j) {} |
void |
util_format_nv12_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) {} |
void |
util_format_nv12_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) {} |
void |
util_format_nv12_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) {} |
void |
util_format_nv12_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height) {} |
void |
util_format_nv12_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j) {} |
void |
util_format_nv21_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) {} |
void |
util_format_nv21_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) {} |
void |
util_format_nv21_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) {} |
void |
util_format_nv21_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height) {} |
void |
util_format_nv21_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j) {} |
void |
util_format_r8g8_r8b8_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) {} |
void |
util_format_r8g8_r8b8_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) {} |
void |
util_format_r8g8_r8b8_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height) {} |
void |
util_format_r8g8_r8b8_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) {} |
void |
util_format_r8g8_r8b8_unorm_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j) {} |
void |
util_format_g8r8_b8r8_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) {} |
void |
util_format_g8r8_b8r8_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) {} |
void |
util_format_g8r8_b8r8_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height) {} |
void |
util_format_g8r8_b8r8_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) {} |
void |
util_format_g8r8_b8r8_unorm_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j) {} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_format_yuv.h |
---|
0,0 → 1,364 |
/************************************************************************** |
* |
* Copyright 2010 VMware, Inc. |
* 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 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 |
* THE COPYRIGHT HOLDERS, 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. |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
**************************************************************************/ |
/** |
* @file |
* YUV colorspace conversion. |
* |
* @author Brian Paul <brianp@vmware.com> |
* @author Michal Krol <michal@vmware.com> |
* @author Jose Fonseca <jfonseca@vmware.com> |
* |
* See also: |
* - http://www.fourcc.org/fccyvrgb.php |
* - http://msdn.microsoft.com/en-us/library/ms893078 |
* - http://en.wikipedia.org/wiki/YUV |
*/ |
#ifndef U_FORMAT_YUV_H_ |
#define U_FORMAT_YUV_H_ |
#include "pipe/p_compiler.h" |
#include "u_math.h" |
/* |
* TODO: Ensure we use consistent and right floating formulas, with enough |
* precision in the coefficients. |
*/ |
static INLINE void |
util_format_rgb_float_to_yuv(float r, float g, float b, |
uint8_t *y, uint8_t *u, uint8_t *v) |
{ |
const float _r = CLAMP(r, 0.0f, 1.0f); |
const float _g = CLAMP(g, 0.0f, 1.0f); |
const float _b = CLAMP(b, 0.0f, 1.0f); |
const float scale = 255.0f; |
const int _y = scale * ( (0.257f * _r) + (0.504f * _g) + (0.098f * _b)); |
const int _u = scale * (-(0.148f * _r) - (0.291f * _g) + (0.439f * _b)); |
const int _v = scale * ( (0.439f * _r) - (0.368f * _g) - (0.071f * _b)); |
*y = _y + 16; |
*u = _u + 128; |
*v = _v + 128; |
} |
static INLINE void |
util_format_yuv_to_rgb_float(uint8_t y, uint8_t u, uint8_t v, |
float *r, float *g, float *b) |
{ |
const int _y = y - 16; |
const int _u = u - 128; |
const int _v = v - 128; |
const float y_factor = 255.0f / 219.0f; |
const float scale = 1.0f / 255.0f; |
*r = scale * (y_factor * _y + 1.596f * _v); |
*g = scale * (y_factor * _y - 0.391f * _u - 0.813f * _v); |
*b = scale * (y_factor * _y + 2.018f * _u ); |
} |
static INLINE void |
util_format_rgb_8unorm_to_yuv(uint8_t r, uint8_t g, uint8_t b, |
uint8_t *y, uint8_t *u, uint8_t *v) |
{ |
*y = (( 66 * r + 129 * g + 25 * b + 128) >> 8) + 16; |
*u = (( -38 * r - 74 * g + 112 * b + 128) >> 8) + 128; |
*v = (( 112 * r - 94 * g - 18 * b + 128) >> 8) + 128; |
} |
static INLINE void |
util_format_yuv_to_rgb_8unorm(uint8_t y, uint8_t u, uint8_t v, |
uint8_t *r, uint8_t *g, uint8_t *b) |
{ |
const int _y = y - 16; |
const int _u = u - 128; |
const int _v = v - 128; |
const int _r = (298 * _y + 409 * _v + 128) >> 8; |
const int _g = (298 * _y - 100 * _u - 208 * _v + 128) >> 8; |
const int _b = (298 * _y + 516 * _u + 128) >> 8; |
*r = CLAMP(_r, 0, 255); |
*g = CLAMP(_g, 0, 255); |
*b = CLAMP(_b, 0, 255); |
} |
void |
util_format_uyvy_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_uyvy_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_uyvy_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_uyvy_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_uyvy_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j); |
void |
util_format_yuyv_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_yuyv_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_yuyv_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_yuyv_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_yuyv_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j); |
/* XXX: Stubbed for now */ |
void |
util_format_yv12_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_yv12_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_yv12_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_yv12_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_yv12_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j); |
void |
util_format_yv16_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_yv16_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_yv16_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_yv16_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_yv16_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j); |
void |
util_format_iyuv_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_iyuv_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_iyuv_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_iyuv_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_iyuv_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j); |
void |
util_format_nv12_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_nv12_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_nv12_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_nv12_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_nv12_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j); |
void |
util_format_nv21_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_nv21_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_nv21_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_nv21_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_nv21_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j); |
void |
util_format_r8g8_b8g8_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_r8g8_b8g8_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_r8g8_b8g8_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_r8g8_b8g8_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_r8g8_b8g8_unorm_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j); |
void |
util_format_g8r8_g8b8_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_g8r8_g8b8_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_g8r8_g8b8_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_g8r8_g8b8_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_g8r8_g8b8_unorm_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j); |
void |
util_format_r8g8_r8b8_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_r8g8_r8b8_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_r8g8_r8b8_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_r8g8_r8b8_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_r8g8_r8b8_unorm_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j); |
void |
util_format_g8r8_b8r8_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_g8r8_b8r8_unorm_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_g8r8_b8r8_unorm_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_g8r8_b8r8_unorm_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height); |
void |
util_format_g8r8_b8r8_unorm_fetch_rgba_float(float *dst, const uint8_t *src, |
unsigned i, unsigned j); |
#endif /* U_FORMAT_YUV_H_ */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_format_zs.c |
---|
0,0 → 1,973 |
/************************************************************************** |
* |
* Copyright 2010 VMware, Inc. |
* 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 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 |
* THE COPYRIGHT HOLDERS, 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. |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
**************************************************************************/ |
#include "u_debug.h" |
#include "u_math.h" |
#include "u_format_zs.h" |
/* |
* z32_unorm conversion functions |
*/ |
static INLINE uint16_t |
z32_unorm_to_z16_unorm(uint32_t z) |
{ |
/* z * 0xffff / 0xffffffff */ |
return z >> 16; |
} |
static INLINE uint32_t |
z16_unorm_to_z32_unorm(uint16_t z) |
{ |
/* z * 0xffffffff / 0xffff */ |
return (z << 16) | z; |
} |
static INLINE uint32_t |
z32_unorm_to_z24_unorm(uint32_t z) |
{ |
/* z * 0xffffff / 0xffffffff */ |
return z >> 8; |
} |
static INLINE uint32_t |
z24_unorm_to_z32_unorm(uint32_t z) |
{ |
/* z * 0xffffffff / 0xffffff */ |
return (z << 8) | (z >> 16); |
} |
/* |
* z32_float conversion functions |
*/ |
static INLINE uint16_t |
z32_float_to_z16_unorm(float z) |
{ |
const float scale = 0xffff; |
return (uint16_t)(z * scale + 0.5f); |
} |
static INLINE float |
z16_unorm_to_z32_float(uint16_t z) |
{ |
const float scale = 1.0 / 0xffff; |
return (float)(z * scale); |
} |
static INLINE uint32_t |
z32_float_to_z24_unorm(float z) |
{ |
const double scale = 0xffffff; |
return (uint32_t)(z * scale) & 0xffffff; |
} |
static INLINE float |
z24_unorm_to_z32_float(uint32_t z) |
{ |
const double scale = 1.0 / 0xffffff; |
return (float)(z * scale); |
} |
static INLINE uint32_t |
z32_float_to_z32_unorm(float z) |
{ |
const double scale = 0xffffffff; |
return (uint32_t)(z * scale); |
} |
static INLINE float |
z32_unorm_to_z32_float(uint32_t z) |
{ |
const double scale = 1.0 / 0xffffffff; |
return (float)(z * scale); |
} |
void |
util_format_s8_uint_unpack_s_8uint(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned y; |
for(y = 0; y < height; ++y) { |
memcpy(dst_row, src_row, width); |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_s8_uint_pack_s_8uint(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned y; |
for(y = 0; y < height; ++y) { |
memcpy(dst_row, src_row, width); |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_z16_unorm_unpack_z_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
float *dst = dst_row; |
const uint16_t *src = (const uint16_t *)src_row; |
for(x = 0; x < width; ++x) { |
uint16_t value = *src++; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap16(value); |
#endif |
*dst++ = z16_unorm_to_z32_float(value); |
} |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_z16_unorm_pack_z_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
const float *src = src_row; |
uint16_t *dst = (uint16_t *)dst_row; |
for(x = 0; x < width; ++x) { |
uint16_t value; |
value = z32_float_to_z16_unorm(*src++); |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap16(value); |
#endif |
*dst++ = value; |
} |
dst_row += dst_stride/sizeof(*dst_row); |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_z16_unorm_unpack_z_32unorm(uint32_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
uint32_t *dst = dst_row; |
const uint16_t *src = (const uint16_t *)src_row; |
for(x = 0; x < width; ++x) { |
uint16_t value = *src++; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap16(value); |
#endif |
*dst++ = z16_unorm_to_z32_unorm(value); |
} |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_z16_unorm_pack_z_32unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint32_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
const uint32_t *src = src_row; |
uint16_t *dst = (uint16_t *)dst_row; |
for(x = 0; x < width; ++x) { |
uint16_t value; |
value = z32_unorm_to_z16_unorm(*src++); |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap16(value); |
#endif |
*dst++ = value; |
} |
dst_row += dst_stride/sizeof(*dst_row); |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_z32_unorm_unpack_z_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
float *dst = dst_row; |
const uint32_t *src = (const uint32_t *)src_row; |
for(x = 0; x < width; ++x) { |
uint32_t value = *src++; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = z32_unorm_to_z32_float(value); |
} |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_z32_unorm_pack_z_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
const float *src = src_row; |
uint32_t *dst = (uint32_t *)dst_row; |
for(x = 0; x < width; ++x) { |
uint32_t value; |
value = z32_float_to_z32_unorm(*src++); |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = value; |
} |
dst_row += dst_stride/sizeof(*dst_row); |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_z32_unorm_unpack_z_32unorm(uint32_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned y; |
for(y = 0; y < height; ++y) { |
memcpy(dst_row, src_row, width * 4); |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_z32_unorm_pack_z_32unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint32_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned y; |
for(y = 0; y < height; ++y) { |
memcpy(dst_row, src_row, width * 4); |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_z32_float_unpack_z_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned y; |
for(y = 0; y < height; ++y) { |
memcpy(dst_row, src_row, width * 4); |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_z32_float_pack_z_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned y; |
for(y = 0; y < height; ++y) { |
memcpy(dst_row, src_row, width * 4); |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_z32_float_unpack_z_32unorm(uint32_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
uint32_t *dst = dst_row; |
const float *src = (const float *)src_row; |
for(x = 0; x < width; ++x) { |
*dst++ = z32_float_to_z32_unorm(*src++); |
} |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_z32_float_pack_z_32unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint32_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
const uint32_t *src = src_row; |
float *dst = (float *)dst_row; |
for(x = 0; x < width; ++x) { |
*dst++ = z32_unorm_to_z32_float(*src++); |
} |
dst_row += dst_stride/sizeof(*dst_row); |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_z24_unorm_s8_uint_unpack_z_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
float *dst = dst_row; |
const uint32_t *src = (const uint32_t *)src_row; |
for(x = 0; x < width; ++x) { |
uint32_t value = *src++; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = z24_unorm_to_z32_float(value & 0xffffff); |
} |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_z24_unorm_s8_uint_pack_z_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
const float *src = src_row; |
uint32_t *dst = (uint32_t *)dst_row; |
for(x = 0; x < width; ++x) { |
uint32_t value = *dst; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
value &= 0xff000000; |
value |= z32_float_to_z24_unorm(*src++); |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = value; |
} |
dst_row += dst_stride/sizeof(*dst_row); |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_z24_unorm_s8_uint_unpack_z_32unorm(uint32_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
uint32_t *dst = dst_row; |
const uint32_t *src = (const uint32_t *)src_row; |
for(x = 0; x < width; ++x) { |
uint32_t value = *src++; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = z24_unorm_to_z32_unorm(value & 0xffffff); |
} |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_z24_unorm_s8_uint_pack_z_32unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint32_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
const uint32_t *src = src_row; |
uint32_t *dst = (uint32_t *)dst_row; |
for(x = 0; x < width; ++x) { |
uint32_t value= *dst; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
value &= 0xff000000; |
value |= z32_unorm_to_z24_unorm(*src++); |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = value; |
} |
dst_row += dst_stride/sizeof(*dst_row); |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_z24_unorm_s8_uint_unpack_s_8uint(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
uint8_t *dst = dst_row; |
const uint32_t *src = (const uint32_t *)src_row; |
for(x = 0; x < width; ++x) { |
uint32_t value = *src++; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = value >> 24; |
} |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_z24_unorm_s8_uint_pack_s_8uint(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
const uint8_t *src = src_row; |
uint32_t *dst = (uint32_t *)dst_row; |
for(x = 0; x < width; ++x) { |
uint32_t value = *dst; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
value &= 0x00ffffff; |
value |= *src++ << 24; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = value; |
} |
dst_row += dst_stride/sizeof(*dst_row); |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_s8_uint_z24_unorm_unpack_z_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
float *dst = dst_row; |
const uint32_t *src = (const uint32_t *)src_row; |
for(x = 0; x < width; ++x) { |
uint32_t value = *src++; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = z24_unorm_to_z32_float(value >> 8); |
} |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_s8_uint_z24_unorm_pack_z_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
const float *src = src_row; |
uint32_t *dst = (uint32_t *)dst_row; |
for(x = 0; x < width; ++x) { |
uint32_t value = *dst; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
value &= 0x000000ff; |
value |= z32_float_to_z24_unorm(*src++) << 8; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = value; |
} |
dst_row += dst_stride/sizeof(*dst_row); |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_s8_uint_z24_unorm_unpack_z_32unorm(uint32_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
uint32_t *dst = dst_row; |
const uint32_t *src = (const uint32_t *)src_row; |
for(x = 0; x < width; ++x) { |
uint32_t value = *src++; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = z24_unorm_to_z32_unorm(value >> 8); |
} |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_s8_uint_z24_unorm_pack_z_32unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint32_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
const uint32_t *src = src_row; |
uint32_t *dst = (uint32_t *)dst_row; |
for(x = 0; x < width; ++x) { |
uint32_t value = *dst; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
value &= 0x000000ff; |
value |= *src++ & 0xffffff00; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = value; |
} |
dst_row += dst_stride/sizeof(*dst_row); |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_s8_uint_z24_unorm_unpack_s_8uint(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
uint8_t *dst = dst_row; |
const uint32_t *src = (const uint32_t *)src_row; |
for(x = 0; x < width; ++x) { |
uint32_t value = *src++; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = value & 0xff; |
} |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_s8_uint_z24_unorm_pack_s_8uint(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
const uint8_t *src = src_row; |
uint32_t *dst = (uint32_t *)dst_row; |
for(x = 0; x < width; ++x) { |
uint32_t value = *dst; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
value &= 0xffffff00; |
value |= *src++; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = value; |
} |
dst_row += dst_stride/sizeof(*dst_row); |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_z24x8_unorm_unpack_z_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
float *dst = dst_row; |
const uint32_t *src = (const uint32_t *)src_row; |
for(x = 0; x < width; ++x) { |
uint32_t value = *src++; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = z24_unorm_to_z32_float(value & 0xffffff); |
} |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_z24x8_unorm_pack_z_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
const float *src = src_row; |
uint32_t *dst = (uint32_t *)dst_row; |
for(x = 0; x < width; ++x) { |
uint32_t value; |
value = z32_float_to_z24_unorm(*src++); |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = value; |
} |
dst_row += dst_stride/sizeof(*dst_row); |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_z24x8_unorm_unpack_z_32unorm(uint32_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
uint32_t *dst = dst_row; |
const uint32_t *src = (const uint32_t *)src_row; |
for(x = 0; x < width; ++x) { |
uint32_t value = *src++; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = z24_unorm_to_z32_unorm(value & 0xffffff); |
} |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_z24x8_unorm_pack_z_32unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint32_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
const uint32_t *src = src_row; |
uint32_t *dst = (uint32_t *)dst_row; |
for(x = 0; x < width; ++x) { |
uint32_t value; |
value = z32_unorm_to_z24_unorm(*src++); |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = value; |
} |
dst_row += dst_stride/sizeof(*dst_row); |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_x8z24_unorm_unpack_z_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
float *dst = dst_row; |
const uint32_t *src = (uint32_t *)src_row; |
for(x = 0; x < width; ++x) { |
uint32_t value = *src++; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = z24_unorm_to_z32_float(value >> 8); |
} |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_x8z24_unorm_pack_z_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
const float *src = src_row; |
uint32_t *dst = (uint32_t *)dst_row; |
for(x = 0; x < width; ++x) { |
uint32_t value; |
value = z32_float_to_z24_unorm(*src++) << 8; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = value; |
} |
dst_row += dst_stride/sizeof(*dst_row); |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_x8z24_unorm_unpack_z_32unorm(uint32_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
uint32_t *dst = dst_row; |
const uint32_t *src = (const uint32_t *)src_row; |
for(x = 0; x < width; ++x) { |
uint32_t value = *src++; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = z24_unorm_to_z32_unorm(value >> 8); |
} |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_x8z24_unorm_pack_z_32unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint32_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
const uint32_t *src = src_row; |
uint32_t *dst = (uint32_t *)dst_row; |
for(x = 0; x < width; ++x) { |
uint32_t value; |
value = z32_unorm_to_z24_unorm(*src++) << 8; |
#ifdef PIPE_ARCH_BIG_ENDIAN |
value = util_bswap32(value); |
#endif |
*dst++ = value; |
} |
dst_row += dst_stride/sizeof(*dst_row); |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_z32_float_s8x24_uint_unpack_z_float(float *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
float *dst = dst_row; |
const float *src = (const float *)src_row; |
for(x = 0; x < width; ++x) { |
*dst = *src; |
src += 2; |
dst += 1; |
} |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_z32_float_s8x24_uint_pack_z_float(uint8_t *dst_row, unsigned dst_stride, |
const float *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
const float *src = src_row; |
float *dst = (float *)dst_row; |
for(x = 0; x < width; ++x) { |
*dst = *src; |
src += 1; |
dst += 2; |
} |
dst_row += dst_stride/sizeof(*dst_row); |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_z32_float_s8x24_uint_unpack_z_32unorm(uint32_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
uint32_t *dst = dst_row; |
const float *src = (const float *)src_row; |
for(x = 0; x < width; ++x) { |
*dst = z32_float_to_z32_unorm(*src); |
src += 2; |
dst += 1; |
} |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_z32_float_s8x24_uint_pack_z_32unorm(uint8_t *dst_row, unsigned dst_stride, |
const uint32_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
const uint32_t *src = src_row; |
float *dst = (float *)dst_row; |
for(x = 0; x < width; ++x) { |
*dst++ = z32_unorm_to_z32_float(*src++); |
} |
dst_row += dst_stride/sizeof(*dst_row); |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_z32_float_s8x24_uint_unpack_s_8uint(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
uint8_t *dst = dst_row; |
const uint8_t *src = src_row + 4; |
for(x = 0; x < width; ++x) { |
*dst = *src; |
src += 8; |
dst += 1; |
} |
src_row += src_stride/sizeof(*src_row); |
dst_row += dst_stride/sizeof(*dst_row); |
} |
} |
void |
util_format_z32_float_s8x24_uint_pack_s_8uint(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
unsigned x, y; |
for(y = 0; y < height; ++y) { |
const uint8_t *src = src_row; |
uint8_t *dst = dst_row + 4; |
for(x = 0; x < width; ++x) { |
*dst = *src; |
src += 1; |
dst += 8; |
} |
dst_row += dst_stride/sizeof(*dst_row); |
src_row += src_stride/sizeof(*src_row); |
} |
} |
void |
util_format_x24s8_uint_unpack_s_8uint(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_z24_unorm_s8_uint_unpack_s_8uint(dst_row, dst_stride, |
src_row, src_stride, |
width, height); |
} |
void |
util_format_x24s8_uint_pack_s_8uint(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_z24_unorm_s8_uint_pack_s_8uint(dst_row, dst_stride, |
src_row, src_stride, |
width, height); |
} |
void |
util_format_s8x24_uint_unpack_s_8uint(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_s8_uint_z24_unorm_unpack_s_8uint(dst_row, dst_stride, |
src_row, src_stride, |
width, height); |
} |
void |
util_format_s8x24_uint_pack_s_8uint(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height) |
{ |
util_format_s8_uint_z24_unorm_pack_s_8uint(dst_row, dst_stride, |
src_row, src_stride, |
width, height); |
} |
void |
util_format_x32_s8x24_uint_unpack_s_8uint(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
util_format_z32_float_s8x24_uint_unpack_s_8uint(dst_row, dst_stride, |
src_row, src_stride, |
width, height); |
} |
void |
util_format_x32_s8x24_uint_pack_s_8uint(uint8_t *dst_row, unsigned dst_stride, |
const uint8_t *src_row, unsigned src_stride, |
unsigned width, unsigned height) |
{ |
util_format_z32_float_s8x24_uint_pack_s_8uint(dst_row, dst_stride, |
src_row, src_stride, |
width, height); |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_format_zs.h |
---|
0,0 → 1,212 |
/************************************************************************** |
* |
* Copyright 2010 VMware, Inc. |
* 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 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 |
* THE COPYRIGHT HOLDERS, 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. |
* |
* The above copyright notice and this permission notice (including the |
* next paragraph) shall be included in all copies or substantial portions |
* of the Software. |
* |
**************************************************************************/ |
#ifndef U_FORMAT_ZS_H_ |
#define U_FORMAT_ZS_H_ |
#include "pipe/p_compiler.h" |
void |
util_format_s8_uint_unpack_s_8uint(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_s8_uint_pack_s_8uint(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_z16_unorm_unpack_z_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_z16_unorm_pack_z_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_z16_unorm_unpack_z_32unorm(uint32_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_z16_unorm_pack_z_32unorm(uint8_t *dst_row, unsigned dst_stride, const uint32_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_z32_unorm_unpack_z_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_z32_unorm_pack_z_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_z32_unorm_unpack_z_32unorm(uint32_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_z32_unorm_pack_z_32unorm(uint8_t *dst_row, unsigned dst_stride, const uint32_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_z32_float_unpack_z_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_z32_float_pack_z_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_z32_float_unpack_z_32unorm(uint32_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_z32_float_pack_z_32unorm(uint8_t *dst_row, unsigned dst_stride, const uint32_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_z24_unorm_s8_uint_unpack_z_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_z24_unorm_s8_uint_pack_z_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_z24_unorm_s8_uint_unpack_z_32unorm(uint32_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_z24_unorm_s8_uint_pack_z_32unorm(uint8_t *dst_row, unsigned dst_stride, const uint32_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_z24_unorm_s8_uint_unpack_s_8uint(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_z24_unorm_s8_uint_pack_s_8uint(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_s8_uint_z24_unorm_unpack_z_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_s8_uint_z24_unorm_pack_z_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_s8_uint_z24_unorm_unpack_z_32unorm(uint32_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_s8_uint_z24_unorm_pack_z_32unorm(uint8_t *dst_row, unsigned dst_stride, const uint32_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_s8_uint_z24_unorm_unpack_s_8uint(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_s8_uint_z24_unorm_pack_s_8uint(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_z24x8_unorm_unpack_z_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_z24x8_unorm_pack_z_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_z24x8_unorm_unpack_z_32unorm(uint32_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_z24x8_unorm_pack_z_32unorm(uint8_t *dst_row, unsigned dst_stride, const uint32_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_x8z24_unorm_unpack_z_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_x8z24_unorm_pack_z_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_x8z24_unorm_unpack_z_32unorm(uint32_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_x8z24_unorm_pack_z_32unorm(uint8_t *dst_row, unsigned dst_stride, const uint32_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_z32_float_s8x24_uint_unpack_z_float(float *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_z32_float_s8x24_uint_pack_z_float(uint8_t *dst_row, unsigned dst_stride, const float *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_z32_float_s8x24_uint_unpack_z_32unorm(uint32_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_z32_float_s8x24_uint_pack_z_32unorm(uint8_t *dst_row, unsigned dst_stride, const uint32_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_z32_float_s8x24_uint_unpack_s_8uint(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_z32_float_s8x24_uint_pack_s_8uint(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_x24s8_uint_unpack_s_8uint(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_x24s8_uint_pack_s_8uint(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_s8x24_uint_unpack_s_8uint(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_s8x24_uint_pack_s_8uint(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_x32_s8x24_uint_unpack_s_8uint(uint8_t *dst_row, unsigned dst_stride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
void |
util_format_x32_s8x24_uint_pack_s_8uint(uint8_t *dst_row, unsigned dst_sride, const uint8_t *src_row, unsigned src_stride, unsigned width, unsigned height); |
#endif /* U_FORMAT_ZS_H_ */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_framebuffer.c |
---|
0,0 → 1,148 |
/************************************************************************** |
* |
* Copyright 2009-2010 VMware, Inc. 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 VMWARE 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. |
* |
**************************************************************************/ |
/** |
* @file |
* Framebuffer utility functions. |
* |
* @author Brian Paul |
*/ |
#include "pipe/p_screen.h" |
#include "pipe/p_state.h" |
#include "pipe/p_defines.h" |
#include "util/u_inlines.h" |
#include "util/u_memory.h" |
#include "util/u_framebuffer.h" |
/** |
* Compare pipe_framebuffer_state objects. |
* \return TRUE if same, FALSE if different |
*/ |
boolean |
util_framebuffer_state_equal(const struct pipe_framebuffer_state *dst, |
const struct pipe_framebuffer_state *src) |
{ |
unsigned i; |
if (dst->width != src->width || |
dst->height != src->height) |
return FALSE; |
for (i = 0; i < Elements(src->cbufs); i++) { |
if (dst->cbufs[i] != src->cbufs[i]) { |
return FALSE; |
} |
} |
if (dst->nr_cbufs != src->nr_cbufs) { |
return FALSE; |
} |
if (dst->zsbuf != src->zsbuf) { |
return FALSE; |
} |
return TRUE; |
} |
/** |
* Copy framebuffer state from src to dst, updating refcounts. |
*/ |
void |
util_copy_framebuffer_state(struct pipe_framebuffer_state *dst, |
const struct pipe_framebuffer_state *src) |
{ |
unsigned i; |
dst->width = src->width; |
dst->height = src->height; |
for (i = 0; i < src->nr_cbufs; i++) |
pipe_surface_reference(&dst->cbufs[i], src->cbufs[i]); |
for (i = src->nr_cbufs; i < dst->nr_cbufs; i++) |
pipe_surface_reference(&dst->cbufs[i], NULL); |
dst->nr_cbufs = src->nr_cbufs; |
pipe_surface_reference(&dst->zsbuf, src->zsbuf); |
} |
void |
util_unreference_framebuffer_state(struct pipe_framebuffer_state *fb) |
{ |
unsigned i; |
for (i = 0; i < fb->nr_cbufs; i++) { |
pipe_surface_reference(&fb->cbufs[i], NULL); |
} |
pipe_surface_reference(&fb->zsbuf, NULL); |
fb->width = fb->height = 0; |
fb->nr_cbufs = 0; |
} |
/* Where multiple sizes are allowed for framebuffer surfaces, find the |
* minimum width and height of all bound surfaces. |
*/ |
boolean |
util_framebuffer_min_size(const struct pipe_framebuffer_state *fb, |
unsigned *width, |
unsigned *height) |
{ |
unsigned w = ~0; |
unsigned h = ~0; |
unsigned i; |
for (i = 0; i < fb->nr_cbufs; i++) { |
w = MIN2(w, fb->cbufs[i]->width); |
h = MIN2(h, fb->cbufs[i]->height); |
} |
if (fb->zsbuf) { |
w = MIN2(w, fb->zsbuf->width); |
h = MIN2(h, fb->zsbuf->height); |
} |
if (w == ~0) { |
*width = 0; |
*height = 0; |
return FALSE; |
} |
else { |
*width = w; |
*height = h; |
return TRUE; |
} |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_framebuffer.h |
---|
0,0 → 1,62 |
/************************************************************************** |
* |
* Copyright 2009-2010 VMware, Inc. 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 VMWARE 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_FRAMEBUFFER_H |
#define U_FRAMEBUFFER_H |
#include "pipe/p_compiler.h" |
#include "pipe/p_state.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
extern boolean |
util_framebuffer_state_equal(const struct pipe_framebuffer_state *dst, |
const struct pipe_framebuffer_state *src); |
extern void |
util_copy_framebuffer_state(struct pipe_framebuffer_state *dst, |
const struct pipe_framebuffer_state *src); |
extern void |
util_unreference_framebuffer_state(struct pipe_framebuffer_state *fb); |
extern boolean |
util_framebuffer_min_size(const struct pipe_framebuffer_state *fb, |
unsigned *width, |
unsigned *height); |
#ifdef __cplusplus |
} |
#endif |
#endif /* U_FRAMEBUFFER_H */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_gen_mipmap.c |
---|
0,0 → 1,1703 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* All Rights Reserved. |
* Copyright 2008 VMware, Inc. 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 TUNGSTEN GRAPHICS 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. |
* |
**************************************************************************/ |
/** |
* @file |
* Mipmap generation utility |
* |
* @author Brian Paul |
*/ |
#include "pipe/p_context.h" |
#include "util/u_debug.h" |
#include "pipe/p_defines.h" |
#include "util/u_inlines.h" |
#include "pipe/p_shader_tokens.h" |
#include "pipe/p_state.h" |
#include "util/u_format.h" |
#include "util/u_memory.h" |
#include "util/u_draw_quad.h" |
#include "util/u_gen_mipmap.h" |
#include "util/u_simple_shaders.h" |
#include "util/u_math.h" |
#include "util/u_texture.h" |
#include "util/u_half.h" |
#include "util/u_surface.h" |
#include "cso_cache/cso_context.h" |
struct gen_mipmap_state |
{ |
struct pipe_context *pipe; |
struct cso_context *cso; |
struct pipe_blend_state blend_keep_color, blend_write_color; |
struct pipe_depth_stencil_alpha_state dsa_keep_depth, dsa_write_depth; |
struct pipe_rasterizer_state rasterizer; |
struct pipe_sampler_state sampler; |
struct pipe_vertex_element velem[2]; |
void *vs; |
/** Not all are used, but simplifies code */ |
void *fs_color[TGSI_TEXTURE_COUNT]; |
void *fs_depth[TGSI_TEXTURE_COUNT]; |
struct pipe_resource *vbuf; /**< quad vertices */ |
unsigned vbuf_slot; |
float vertices[4][2][4]; /**< vertex/texcoords for quad */ |
}; |
enum dtype |
{ |
DTYPE_UBYTE, |
DTYPE_UBYTE_3_3_2, |
DTYPE_USHORT, |
DTYPE_USHORT_4_4_4_4, |
DTYPE_USHORT_5_6_5, |
DTYPE_USHORT_1_5_5_5_REV, |
DTYPE_UINT, |
DTYPE_FLOAT, |
DTYPE_HALF_FLOAT |
}; |
typedef uint16_t half_float; |
/** |
* \name Support macros for do_row and do_row_3d |
* |
* The macro madness is here for two reasons. First, it compacts the code |
* slightly. Second, it makes it much easier to adjust the specifics of the |
* filter to tune the rounding characteristics. |
*/ |
/*@{*/ |
#define DECLARE_ROW_POINTERS(t, e) \ |
const t(*rowA)[e] = (const t(*)[e]) srcRowA; \ |
const t(*rowB)[e] = (const t(*)[e]) srcRowB; \ |
const t(*rowC)[e] = (const t(*)[e]) srcRowC; \ |
const t(*rowD)[e] = (const t(*)[e]) srcRowD; \ |
t(*dst)[e] = (t(*)[e]) dstRow |
#define DECLARE_ROW_POINTERS0(t) \ |
const t *rowA = (const t *) srcRowA; \ |
const t *rowB = (const t *) srcRowB; \ |
const t *rowC = (const t *) srcRowC; \ |
const t *rowD = (const t *) srcRowD; \ |
t *dst = (t *) dstRow |
#define FILTER_SUM_3D(Aj, Ak, Bj, Bk, Cj, Ck, Dj, Dk) \ |
((unsigned) Aj + (unsigned) Ak \ |
+ (unsigned) Bj + (unsigned) Bk \ |
+ (unsigned) Cj + (unsigned) Ck \ |
+ (unsigned) Dj + (unsigned) Dk \ |
+ 4) >> 3 |
#define FILTER_3D(e) \ |
do { \ |
dst[i][e] = FILTER_SUM_3D(rowA[j][e], rowA[k][e], \ |
rowB[j][e], rowB[k][e], \ |
rowC[j][e], rowC[k][e], \ |
rowD[j][e], rowD[k][e]); \ |
} while(0) |
#define FILTER_F_3D(e) \ |
do { \ |
dst[i][e] = (rowA[j][e] + rowA[k][e] \ |
+ rowB[j][e] + rowB[k][e] \ |
+ rowC[j][e] + rowC[k][e] \ |
+ rowD[j][e] + rowD[k][e]) * 0.125F; \ |
} while(0) |
#define FILTER_HF_3D(e) \ |
do { \ |
const float aj = util_half_to_float(rowA[j][e]); \ |
const float ak = util_half_to_float(rowA[k][e]); \ |
const float bj = util_half_to_float(rowB[j][e]); \ |
const float bk = util_half_to_float(rowB[k][e]); \ |
const float cj = util_half_to_float(rowC[j][e]); \ |
const float ck = util_half_to_float(rowC[k][e]); \ |
const float dj = util_half_to_float(rowD[j][e]); \ |
const float dk = util_half_to_float(rowD[k][e]); \ |
dst[i][e] = util_float_to_half((aj + ak + bj + bk + cj + ck + dj + dk) \ |
* 0.125F); \ |
} while(0) |
/*@}*/ |
/** |
* Average together two rows of a source image to produce a single new |
* row in the dest image. It's legal for the two source rows to point |
* to the same data. The source width must be equal to either the |
* dest width or two times the dest width. |
* \param datatype GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, GL_FLOAT, etc. |
* \param comps number of components per pixel (1..4) |
*/ |
static void |
do_row(enum dtype datatype, uint comps, int srcWidth, |
const void *srcRowA, const void *srcRowB, |
int dstWidth, void *dstRow) |
{ |
const uint k0 = (srcWidth == dstWidth) ? 0 : 1; |
const uint colStride = (srcWidth == dstWidth) ? 1 : 2; |
assert(comps >= 1); |
assert(comps <= 4); |
/* This assertion is no longer valid with non-power-of-2 textures |
assert(srcWidth == dstWidth || srcWidth == 2 * dstWidth); |
*/ |
if (datatype == DTYPE_UBYTE && comps == 4) { |
uint i, j, k; |
const ubyte(*rowA)[4] = (const ubyte(*)[4]) srcRowA; |
const ubyte(*rowB)[4] = (const ubyte(*)[4]) srcRowB; |
ubyte(*dst)[4] = (ubyte(*)[4]) dstRow; |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; |
dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; |
dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4; |
dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4; |
} |
} |
else if (datatype == DTYPE_UBYTE && comps == 3) { |
uint i, j, k; |
const ubyte(*rowA)[3] = (const ubyte(*)[3]) srcRowA; |
const ubyte(*rowB)[3] = (const ubyte(*)[3]) srcRowB; |
ubyte(*dst)[3] = (ubyte(*)[3]) dstRow; |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; |
dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; |
dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4; |
} |
} |
else if (datatype == DTYPE_UBYTE && comps == 2) { |
uint i, j, k; |
const ubyte(*rowA)[2] = (const ubyte(*)[2]) srcRowA; |
const ubyte(*rowB)[2] = (const ubyte(*)[2]) srcRowB; |
ubyte(*dst)[2] = (ubyte(*)[2]) dstRow; |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) >> 2; |
dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) >> 2; |
} |
} |
else if (datatype == DTYPE_UBYTE && comps == 1) { |
uint i, j, k; |
const ubyte *rowA = (const ubyte *) srcRowA; |
const ubyte *rowB = (const ubyte *) srcRowB; |
ubyte *dst = (ubyte *) dstRow; |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) >> 2; |
} |
} |
else if (datatype == DTYPE_USHORT && comps == 4) { |
uint i, j, k; |
const ushort(*rowA)[4] = (const ushort(*)[4]) srcRowA; |
const ushort(*rowB)[4] = (const ushort(*)[4]) srcRowB; |
ushort(*dst)[4] = (ushort(*)[4]) dstRow; |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; |
dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; |
dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4; |
dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4; |
} |
} |
else if (datatype == DTYPE_USHORT && comps == 3) { |
uint i, j, k; |
const ushort(*rowA)[3] = (const ushort(*)[3]) srcRowA; |
const ushort(*rowB)[3] = (const ushort(*)[3]) srcRowB; |
ushort(*dst)[3] = (ushort(*)[3]) dstRow; |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; |
dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; |
dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4; |
} |
} |
else if (datatype == DTYPE_USHORT && comps == 2) { |
uint i, j, k; |
const ushort(*rowA)[2] = (const ushort(*)[2]) srcRowA; |
const ushort(*rowB)[2] = (const ushort(*)[2]) srcRowB; |
ushort(*dst)[2] = (ushort(*)[2]) dstRow; |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; |
dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; |
} |
} |
else if (datatype == DTYPE_USHORT && comps == 1) { |
uint i, j, k; |
const ushort *rowA = (const ushort *) srcRowA; |
const ushort *rowB = (const ushort *) srcRowB; |
ushort *dst = (ushort *) dstRow; |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4; |
} |
} |
else if (datatype == DTYPE_FLOAT && comps == 4) { |
uint i, j, k; |
const float(*rowA)[4] = (const float(*)[4]) srcRowA; |
const float(*rowB)[4] = (const float(*)[4]) srcRowB; |
float(*dst)[4] = (float(*)[4]) dstRow; |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
dst[i][0] = (rowA[j][0] + rowA[k][0] + |
rowB[j][0] + rowB[k][0]) * 0.25F; |
dst[i][1] = (rowA[j][1] + rowA[k][1] + |
rowB[j][1] + rowB[k][1]) * 0.25F; |
dst[i][2] = (rowA[j][2] + rowA[k][2] + |
rowB[j][2] + rowB[k][2]) * 0.25F; |
dst[i][3] = (rowA[j][3] + rowA[k][3] + |
rowB[j][3] + rowB[k][3]) * 0.25F; |
} |
} |
else if (datatype == DTYPE_FLOAT && comps == 3) { |
uint i, j, k; |
const float(*rowA)[3] = (const float(*)[3]) srcRowA; |
const float(*rowB)[3] = (const float(*)[3]) srcRowB; |
float(*dst)[3] = (float(*)[3]) dstRow; |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
dst[i][0] = (rowA[j][0] + rowA[k][0] + |
rowB[j][0] + rowB[k][0]) * 0.25F; |
dst[i][1] = (rowA[j][1] + rowA[k][1] + |
rowB[j][1] + rowB[k][1]) * 0.25F; |
dst[i][2] = (rowA[j][2] + rowA[k][2] + |
rowB[j][2] + rowB[k][2]) * 0.25F; |
} |
} |
else if (datatype == DTYPE_FLOAT && comps == 2) { |
uint i, j, k; |
const float(*rowA)[2] = (const float(*)[2]) srcRowA; |
const float(*rowB)[2] = (const float(*)[2]) srcRowB; |
float(*dst)[2] = (float(*)[2]) dstRow; |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
dst[i][0] = (rowA[j][0] + rowA[k][0] + |
rowB[j][0] + rowB[k][0]) * 0.25F; |
dst[i][1] = (rowA[j][1] + rowA[k][1] + |
rowB[j][1] + rowB[k][1]) * 0.25F; |
} |
} |
else if (datatype == DTYPE_FLOAT && comps == 1) { |
uint i, j, k; |
const float *rowA = (const float *) srcRowA; |
const float *rowB = (const float *) srcRowB; |
float *dst = (float *) dstRow; |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F; |
} |
} |
else if (datatype == DTYPE_HALF_FLOAT && comps == 4) { |
uint i, j, k, comp; |
const half_float(*rowA)[4] = (const half_float(*)[4]) srcRowA; |
const half_float(*rowB)[4] = (const half_float(*)[4]) srcRowB; |
half_float(*dst)[4] = (half_float(*)[4]) dstRow; |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
for (comp = 0; comp < 4; comp++) { |
float aj, ak, bj, bk; |
aj = util_half_to_float(rowA[j][comp]); |
ak = util_half_to_float(rowA[k][comp]); |
bj = util_half_to_float(rowB[j][comp]); |
bk = util_half_to_float(rowB[k][comp]); |
dst[i][comp] = util_float_to_half((aj + ak + bj + bk) * 0.25F); |
} |
} |
} |
else if (datatype == DTYPE_HALF_FLOAT && comps == 3) { |
uint i, j, k, comp; |
const half_float(*rowA)[3] = (const half_float(*)[3]) srcRowA; |
const half_float(*rowB)[3] = (const half_float(*)[3]) srcRowB; |
half_float(*dst)[3] = (half_float(*)[3]) dstRow; |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
for (comp = 0; comp < 3; comp++) { |
float aj, ak, bj, bk; |
aj = util_half_to_float(rowA[j][comp]); |
ak = util_half_to_float(rowA[k][comp]); |
bj = util_half_to_float(rowB[j][comp]); |
bk = util_half_to_float(rowB[k][comp]); |
dst[i][comp] = util_float_to_half((aj + ak + bj + bk) * 0.25F); |
} |
} |
} |
else if (datatype == DTYPE_HALF_FLOAT && comps == 2) { |
uint i, j, k, comp; |
const half_float(*rowA)[2] = (const half_float(*)[2]) srcRowA; |
const half_float(*rowB)[2] = (const half_float(*)[2]) srcRowB; |
half_float(*dst)[2] = (half_float(*)[2]) dstRow; |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
for (comp = 0; comp < 2; comp++) { |
float aj, ak, bj, bk; |
aj = util_half_to_float(rowA[j][comp]); |
ak = util_half_to_float(rowA[k][comp]); |
bj = util_half_to_float(rowB[j][comp]); |
bk = util_half_to_float(rowB[k][comp]); |
dst[i][comp] = util_float_to_half((aj + ak + bj + bk) * 0.25F); |
} |
} |
} |
else if (datatype == DTYPE_HALF_FLOAT && comps == 1) { |
uint i, j, k; |
const half_float *rowA = (const half_float *) srcRowA; |
const half_float *rowB = (const half_float *) srcRowB; |
half_float *dst = (half_float *) dstRow; |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
float aj, ak, bj, bk; |
aj = util_half_to_float(rowA[j]); |
ak = util_half_to_float(rowA[k]); |
bj = util_half_to_float(rowB[j]); |
bk = util_half_to_float(rowB[k]); |
dst[i] = util_float_to_half((aj + ak + bj + bk) * 0.25F); |
} |
} |
else if (datatype == DTYPE_UINT && comps == 1) { |
uint i, j, k; |
const uint *rowA = (const uint *) srcRowA; |
const uint *rowB = (const uint *) srcRowB; |
uint *dst = (uint *) dstRow; |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
dst[i] = rowA[j] / 4 + rowA[k] / 4 + rowB[j] / 4 + rowB[k] / 4; |
} |
} |
else if (datatype == DTYPE_USHORT_5_6_5 && comps == 3) { |
uint i, j, k; |
const ushort *rowA = (const ushort *) srcRowA; |
const ushort *rowB = (const ushort *) srcRowB; |
ushort *dst = (ushort *) dstRow; |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
const int rowAr0 = rowA[j] & 0x1f; |
const int rowAr1 = rowA[k] & 0x1f; |
const int rowBr0 = rowB[j] & 0x1f; |
const int rowBr1 = rowB[k] & 0x1f; |
const int rowAg0 = (rowA[j] >> 5) & 0x3f; |
const int rowAg1 = (rowA[k] >> 5) & 0x3f; |
const int rowBg0 = (rowB[j] >> 5) & 0x3f; |
const int rowBg1 = (rowB[k] >> 5) & 0x3f; |
const int rowAb0 = (rowA[j] >> 11) & 0x1f; |
const int rowAb1 = (rowA[k] >> 11) & 0x1f; |
const int rowBb0 = (rowB[j] >> 11) & 0x1f; |
const int rowBb1 = (rowB[k] >> 11) & 0x1f; |
const int red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; |
const int green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; |
const int blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; |
dst[i] = (blue << 11) | (green << 5) | red; |
} |
} |
else if (datatype == DTYPE_USHORT_4_4_4_4 && comps == 4) { |
uint i, j, k; |
const ushort *rowA = (const ushort *) srcRowA; |
const ushort *rowB = (const ushort *) srcRowB; |
ushort *dst = (ushort *) dstRow; |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
const int rowAr0 = rowA[j] & 0xf; |
const int rowAr1 = rowA[k] & 0xf; |
const int rowBr0 = rowB[j] & 0xf; |
const int rowBr1 = rowB[k] & 0xf; |
const int rowAg0 = (rowA[j] >> 4) & 0xf; |
const int rowAg1 = (rowA[k] >> 4) & 0xf; |
const int rowBg0 = (rowB[j] >> 4) & 0xf; |
const int rowBg1 = (rowB[k] >> 4) & 0xf; |
const int rowAb0 = (rowA[j] >> 8) & 0xf; |
const int rowAb1 = (rowA[k] >> 8) & 0xf; |
const int rowBb0 = (rowB[j] >> 8) & 0xf; |
const int rowBb1 = (rowB[k] >> 8) & 0xf; |
const int rowAa0 = (rowA[j] >> 12) & 0xf; |
const int rowAa1 = (rowA[k] >> 12) & 0xf; |
const int rowBa0 = (rowB[j] >> 12) & 0xf; |
const int rowBa1 = (rowB[k] >> 12) & 0xf; |
const int red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; |
const int green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; |
const int blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; |
const int alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2; |
dst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red; |
} |
} |
else if (datatype == DTYPE_USHORT_1_5_5_5_REV && comps == 4) { |
uint i, j, k; |
const ushort *rowA = (const ushort *) srcRowA; |
const ushort *rowB = (const ushort *) srcRowB; |
ushort *dst = (ushort *) dstRow; |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
const int rowAr0 = rowA[j] & 0x1f; |
const int rowAr1 = rowA[k] & 0x1f; |
const int rowBr0 = rowB[j] & 0x1f; |
const int rowBr1 = rowB[k] & 0x1f; |
const int rowAg0 = (rowA[j] >> 5) & 0x1f; |
const int rowAg1 = (rowA[k] >> 5) & 0x1f; |
const int rowBg0 = (rowB[j] >> 5) & 0x1f; |
const int rowBg1 = (rowB[k] >> 5) & 0x1f; |
const int rowAb0 = (rowA[j] >> 10) & 0x1f; |
const int rowAb1 = (rowA[k] >> 10) & 0x1f; |
const int rowBb0 = (rowB[j] >> 10) & 0x1f; |
const int rowBb1 = (rowB[k] >> 10) & 0x1f; |
const int rowAa0 = (rowA[j] >> 15) & 0x1; |
const int rowAa1 = (rowA[k] >> 15) & 0x1; |
const int rowBa0 = (rowB[j] >> 15) & 0x1; |
const int rowBa1 = (rowB[k] >> 15) & 0x1; |
const int red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; |
const int green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; |
const int blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; |
const int alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2; |
dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red; |
} |
} |
else if (datatype == DTYPE_UBYTE_3_3_2 && comps == 3) { |
uint i, j, k; |
const ubyte *rowA = (const ubyte *) srcRowA; |
const ubyte *rowB = (const ubyte *) srcRowB; |
ubyte *dst = (ubyte *) dstRow; |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
const int rowAr0 = rowA[j] & 0x3; |
const int rowAr1 = rowA[k] & 0x3; |
const int rowBr0 = rowB[j] & 0x3; |
const int rowBr1 = rowB[k] & 0x3; |
const int rowAg0 = (rowA[j] >> 2) & 0x7; |
const int rowAg1 = (rowA[k] >> 2) & 0x7; |
const int rowBg0 = (rowB[j] >> 2) & 0x7; |
const int rowBg1 = (rowB[k] >> 2) & 0x7; |
const int rowAb0 = (rowA[j] >> 5) & 0x7; |
const int rowAb1 = (rowA[k] >> 5) & 0x7; |
const int rowBb0 = (rowB[j] >> 5) & 0x7; |
const int rowBb1 = (rowB[k] >> 5) & 0x7; |
const int red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; |
const int green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; |
const int blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; |
dst[i] = (blue << 5) | (green << 2) | red; |
} |
} |
else { |
debug_printf("bad format in do_row()"); |
} |
} |
/** |
* Average together four rows of a source image to produce a single new |
* row in the dest image. It's legal for the two source rows to point |
* to the same data. The source width must be equal to either the |
* dest width or two times the dest width. |
* |
* \param datatype GL pixel type \c GL_UNSIGNED_BYTE, \c GL_UNSIGNED_SHORT, |
* \c GL_FLOAT, etc. |
* \param comps number of components per pixel (1..4) |
* \param srcWidth Width of a row in the source data |
* \param srcRowA Pointer to one of the rows of source data |
* \param srcRowB Pointer to one of the rows of source data |
* \param srcRowC Pointer to one of the rows of source data |
* \param srcRowD Pointer to one of the rows of source data |
* \param dstWidth Width of a row in the destination data |
* \param srcRowA Pointer to the row of destination data |
*/ |
static void |
do_row_3D(enum dtype datatype, uint comps, int srcWidth, |
const void *srcRowA, const void *srcRowB, |
const void *srcRowC, const void *srcRowD, |
int dstWidth, void *dstRow) |
{ |
const uint k0 = (srcWidth == dstWidth) ? 0 : 1; |
const uint colStride = (srcWidth == dstWidth) ? 1 : 2; |
uint i, j, k; |
assert(comps >= 1); |
assert(comps <= 4); |
if ((datatype == DTYPE_UBYTE) && (comps == 4)) { |
DECLARE_ROW_POINTERS(ubyte, 4); |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
FILTER_3D(0); |
FILTER_3D(1); |
FILTER_3D(2); |
FILTER_3D(3); |
} |
} |
else if ((datatype == DTYPE_UBYTE) && (comps == 3)) { |
DECLARE_ROW_POINTERS(ubyte, 3); |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
FILTER_3D(0); |
FILTER_3D(1); |
FILTER_3D(2); |
} |
} |
else if ((datatype == DTYPE_UBYTE) && (comps == 2)) { |
DECLARE_ROW_POINTERS(ubyte, 2); |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
FILTER_3D(0); |
FILTER_3D(1); |
} |
} |
else if ((datatype == DTYPE_UBYTE) && (comps == 1)) { |
DECLARE_ROW_POINTERS(ubyte, 1); |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
FILTER_3D(0); |
} |
} |
else if ((datatype == DTYPE_USHORT) && (comps == 4)) { |
DECLARE_ROW_POINTERS(ushort, 4); |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
FILTER_3D(0); |
FILTER_3D(1); |
FILTER_3D(2); |
FILTER_3D(3); |
} |
} |
else if ((datatype == DTYPE_USHORT) && (comps == 3)) { |
DECLARE_ROW_POINTERS(ushort, 3); |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
FILTER_3D(0); |
FILTER_3D(1); |
FILTER_3D(2); |
} |
} |
else if ((datatype == DTYPE_USHORT) && (comps == 2)) { |
DECLARE_ROW_POINTERS(ushort, 2); |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
FILTER_3D(0); |
FILTER_3D(1); |
} |
} |
else if ((datatype == DTYPE_USHORT) && (comps == 1)) { |
DECLARE_ROW_POINTERS(ushort, 1); |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
FILTER_3D(0); |
} |
} |
else if ((datatype == DTYPE_FLOAT) && (comps == 4)) { |
DECLARE_ROW_POINTERS(float, 4); |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
FILTER_F_3D(0); |
FILTER_F_3D(1); |
FILTER_F_3D(2); |
FILTER_F_3D(3); |
} |
} |
else if ((datatype == DTYPE_FLOAT) && (comps == 3)) { |
DECLARE_ROW_POINTERS(float, 3); |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
FILTER_F_3D(0); |
FILTER_F_3D(1); |
FILTER_F_3D(2); |
} |
} |
else if ((datatype == DTYPE_FLOAT) && (comps == 2)) { |
DECLARE_ROW_POINTERS(float, 2); |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
FILTER_F_3D(0); |
FILTER_F_3D(1); |
} |
} |
else if ((datatype == DTYPE_FLOAT) && (comps == 1)) { |
DECLARE_ROW_POINTERS(float, 1); |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
FILTER_F_3D(0); |
} |
} |
else if ((datatype == DTYPE_HALF_FLOAT) && (comps == 4)) { |
DECLARE_ROW_POINTERS(half_float, 4); |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
FILTER_HF_3D(0); |
FILTER_HF_3D(1); |
FILTER_HF_3D(2); |
FILTER_HF_3D(3); |
} |
} |
else if ((datatype == DTYPE_HALF_FLOAT) && (comps == 3)) { |
DECLARE_ROW_POINTERS(half_float, 4); |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
FILTER_HF_3D(0); |
FILTER_HF_3D(1); |
FILTER_HF_3D(2); |
} |
} |
else if ((datatype == DTYPE_HALF_FLOAT) && (comps == 2)) { |
DECLARE_ROW_POINTERS(half_float, 4); |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
FILTER_HF_3D(0); |
FILTER_HF_3D(1); |
} |
} |
else if ((datatype == DTYPE_HALF_FLOAT) && (comps == 1)) { |
DECLARE_ROW_POINTERS(half_float, 4); |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
FILTER_HF_3D(0); |
} |
} |
else if ((datatype == DTYPE_UINT) && (comps == 1)) { |
const uint *rowA = (const uint *) srcRowA; |
const uint *rowB = (const uint *) srcRowB; |
const uint *rowC = (const uint *) srcRowC; |
const uint *rowD = (const uint *) srcRowD; |
float *dst = (float *) dstRow; |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
const uint64_t tmp = (((uint64_t) rowA[j] + (uint64_t) rowA[k]) |
+ ((uint64_t) rowB[j] + (uint64_t) rowB[k]) |
+ ((uint64_t) rowC[j] + (uint64_t) rowC[k]) |
+ ((uint64_t) rowD[j] + (uint64_t) rowD[k])); |
dst[i] = (float)((double) tmp * 0.125); |
} |
} |
else if ((datatype == DTYPE_USHORT_5_6_5) && (comps == 3)) { |
DECLARE_ROW_POINTERS0(ushort); |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
const int rowAr0 = rowA[j] & 0x1f; |
const int rowAr1 = rowA[k] & 0x1f; |
const int rowBr0 = rowB[j] & 0x1f; |
const int rowBr1 = rowB[k] & 0x1f; |
const int rowCr0 = rowC[j] & 0x1f; |
const int rowCr1 = rowC[k] & 0x1f; |
const int rowDr0 = rowD[j] & 0x1f; |
const int rowDr1 = rowD[k] & 0x1f; |
const int rowAg0 = (rowA[j] >> 5) & 0x3f; |
const int rowAg1 = (rowA[k] >> 5) & 0x3f; |
const int rowBg0 = (rowB[j] >> 5) & 0x3f; |
const int rowBg1 = (rowB[k] >> 5) & 0x3f; |
const int rowCg0 = (rowC[j] >> 5) & 0x3f; |
const int rowCg1 = (rowC[k] >> 5) & 0x3f; |
const int rowDg0 = (rowD[j] >> 5) & 0x3f; |
const int rowDg1 = (rowD[k] >> 5) & 0x3f; |
const int rowAb0 = (rowA[j] >> 11) & 0x1f; |
const int rowAb1 = (rowA[k] >> 11) & 0x1f; |
const int rowBb0 = (rowB[j] >> 11) & 0x1f; |
const int rowBb1 = (rowB[k] >> 11) & 0x1f; |
const int rowCb0 = (rowC[j] >> 11) & 0x1f; |
const int rowCb1 = (rowC[k] >> 11) & 0x1f; |
const int rowDb0 = (rowD[j] >> 11) & 0x1f; |
const int rowDb1 = (rowD[k] >> 11) & 0x1f; |
const int r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1, |
rowCr0, rowCr1, rowDr0, rowDr1); |
const int g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1, |
rowCg0, rowCg1, rowDg0, rowDg1); |
const int b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1, |
rowCb0, rowCb1, rowDb0, rowDb1); |
dst[i] = (b << 11) | (g << 5) | r; |
} |
} |
else if ((datatype == DTYPE_USHORT_4_4_4_4) && (comps == 4)) { |
DECLARE_ROW_POINTERS0(ushort); |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
const int rowAr0 = rowA[j] & 0xf; |
const int rowAr1 = rowA[k] & 0xf; |
const int rowBr0 = rowB[j] & 0xf; |
const int rowBr1 = rowB[k] & 0xf; |
const int rowCr0 = rowC[j] & 0xf; |
const int rowCr1 = rowC[k] & 0xf; |
const int rowDr0 = rowD[j] & 0xf; |
const int rowDr1 = rowD[k] & 0xf; |
const int rowAg0 = (rowA[j] >> 4) & 0xf; |
const int rowAg1 = (rowA[k] >> 4) & 0xf; |
const int rowBg0 = (rowB[j] >> 4) & 0xf; |
const int rowBg1 = (rowB[k] >> 4) & 0xf; |
const int rowCg0 = (rowC[j] >> 4) & 0xf; |
const int rowCg1 = (rowC[k] >> 4) & 0xf; |
const int rowDg0 = (rowD[j] >> 4) & 0xf; |
const int rowDg1 = (rowD[k] >> 4) & 0xf; |
const int rowAb0 = (rowA[j] >> 8) & 0xf; |
const int rowAb1 = (rowA[k] >> 8) & 0xf; |
const int rowBb0 = (rowB[j] >> 8) & 0xf; |
const int rowBb1 = (rowB[k] >> 8) & 0xf; |
const int rowCb0 = (rowC[j] >> 8) & 0xf; |
const int rowCb1 = (rowC[k] >> 8) & 0xf; |
const int rowDb0 = (rowD[j] >> 8) & 0xf; |
const int rowDb1 = (rowD[k] >> 8) & 0xf; |
const int rowAa0 = (rowA[j] >> 12) & 0xf; |
const int rowAa1 = (rowA[k] >> 12) & 0xf; |
const int rowBa0 = (rowB[j] >> 12) & 0xf; |
const int rowBa1 = (rowB[k] >> 12) & 0xf; |
const int rowCa0 = (rowC[j] >> 12) & 0xf; |
const int rowCa1 = (rowC[k] >> 12) & 0xf; |
const int rowDa0 = (rowD[j] >> 12) & 0xf; |
const int rowDa1 = (rowD[k] >> 12) & 0xf; |
const int r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1, |
rowCr0, rowCr1, rowDr0, rowDr1); |
const int g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1, |
rowCg0, rowCg1, rowDg0, rowDg1); |
const int b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1, |
rowCb0, rowCb1, rowDb0, rowDb1); |
const int a = FILTER_SUM_3D(rowAa0, rowAa1, rowBa0, rowBa1, |
rowCa0, rowCa1, rowDa0, rowDa1); |
dst[i] = (a << 12) | (b << 8) | (g << 4) | r; |
} |
} |
else if ((datatype == DTYPE_USHORT_1_5_5_5_REV) && (comps == 4)) { |
DECLARE_ROW_POINTERS0(ushort); |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
const int rowAr0 = rowA[j] & 0x1f; |
const int rowAr1 = rowA[k] & 0x1f; |
const int rowBr0 = rowB[j] & 0x1f; |
const int rowBr1 = rowB[k] & 0x1f; |
const int rowCr0 = rowC[j] & 0x1f; |
const int rowCr1 = rowC[k] & 0x1f; |
const int rowDr0 = rowD[j] & 0x1f; |
const int rowDr1 = rowD[k] & 0x1f; |
const int rowAg0 = (rowA[j] >> 5) & 0x1f; |
const int rowAg1 = (rowA[k] >> 5) & 0x1f; |
const int rowBg0 = (rowB[j] >> 5) & 0x1f; |
const int rowBg1 = (rowB[k] >> 5) & 0x1f; |
const int rowCg0 = (rowC[j] >> 5) & 0x1f; |
const int rowCg1 = (rowC[k] >> 5) & 0x1f; |
const int rowDg0 = (rowD[j] >> 5) & 0x1f; |
const int rowDg1 = (rowD[k] >> 5) & 0x1f; |
const int rowAb0 = (rowA[j] >> 10) & 0x1f; |
const int rowAb1 = (rowA[k] >> 10) & 0x1f; |
const int rowBb0 = (rowB[j] >> 10) & 0x1f; |
const int rowBb1 = (rowB[k] >> 10) & 0x1f; |
const int rowCb0 = (rowC[j] >> 10) & 0x1f; |
const int rowCb1 = (rowC[k] >> 10) & 0x1f; |
const int rowDb0 = (rowD[j] >> 10) & 0x1f; |
const int rowDb1 = (rowD[k] >> 10) & 0x1f; |
const int rowAa0 = (rowA[j] >> 15) & 0x1; |
const int rowAa1 = (rowA[k] >> 15) & 0x1; |
const int rowBa0 = (rowB[j] >> 15) & 0x1; |
const int rowBa1 = (rowB[k] >> 15) & 0x1; |
const int rowCa0 = (rowC[j] >> 15) & 0x1; |
const int rowCa1 = (rowC[k] >> 15) & 0x1; |
const int rowDa0 = (rowD[j] >> 15) & 0x1; |
const int rowDa1 = (rowD[k] >> 15) & 0x1; |
const int r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1, |
rowCr0, rowCr1, rowDr0, rowDr1); |
const int g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1, |
rowCg0, rowCg1, rowDg0, rowDg1); |
const int b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1, |
rowCb0, rowCb1, rowDb0, rowDb1); |
const int a = FILTER_SUM_3D(rowAa0, rowAa1, rowBa0, rowBa1, |
rowCa0, rowCa1, rowDa0, rowDa1); |
dst[i] = (a << 15) | (b << 10) | (g << 5) | r; |
} |
} |
else if ((datatype == DTYPE_UBYTE_3_3_2) && (comps == 3)) { |
DECLARE_ROW_POINTERS0(ushort); |
for (i = j = 0, k = k0; i < (uint) dstWidth; |
i++, j += colStride, k += colStride) { |
const int rowAr0 = rowA[j] & 0x3; |
const int rowAr1 = rowA[k] & 0x3; |
const int rowBr0 = rowB[j] & 0x3; |
const int rowBr1 = rowB[k] & 0x3; |
const int rowCr0 = rowC[j] & 0x3; |
const int rowCr1 = rowC[k] & 0x3; |
const int rowDr0 = rowD[j] & 0x3; |
const int rowDr1 = rowD[k] & 0x3; |
const int rowAg0 = (rowA[j] >> 2) & 0x7; |
const int rowAg1 = (rowA[k] >> 2) & 0x7; |
const int rowBg0 = (rowB[j] >> 2) & 0x7; |
const int rowBg1 = (rowB[k] >> 2) & 0x7; |
const int rowCg0 = (rowC[j] >> 2) & 0x7; |
const int rowCg1 = (rowC[k] >> 2) & 0x7; |
const int rowDg0 = (rowD[j] >> 2) & 0x7; |
const int rowDg1 = (rowD[k] >> 2) & 0x7; |
const int rowAb0 = (rowA[j] >> 5) & 0x7; |
const int rowAb1 = (rowA[k] >> 5) & 0x7; |
const int rowBb0 = (rowB[j] >> 5) & 0x7; |
const int rowBb1 = (rowB[k] >> 5) & 0x7; |
const int rowCb0 = (rowC[j] >> 5) & 0x7; |
const int rowCb1 = (rowC[k] >> 5) & 0x7; |
const int rowDb0 = (rowD[j] >> 5) & 0x7; |
const int rowDb1 = (rowD[k] >> 5) & 0x7; |
const int r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1, |
rowCr0, rowCr1, rowDr0, rowDr1); |
const int g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1, |
rowCg0, rowCg1, rowDg0, rowDg1); |
const int b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1, |
rowCb0, rowCb1, rowDb0, rowDb1); |
dst[i] = (b << 5) | (g << 2) | r; |
} |
} |
else { |
debug_printf("bad format in do_row_3D()"); |
} |
} |
static void |
format_to_type_comps(enum pipe_format pformat, |
enum dtype *datatype, uint *comps) |
{ |
/* XXX I think this could be implemented in terms of the pf_*() functions */ |
switch (pformat) { |
case PIPE_FORMAT_B8G8R8A8_UNORM: |
case PIPE_FORMAT_B8G8R8X8_UNORM: |
case PIPE_FORMAT_A8R8G8B8_UNORM: |
case PIPE_FORMAT_X8R8G8B8_UNORM: |
case PIPE_FORMAT_A8B8G8R8_SRGB: |
case PIPE_FORMAT_X8B8G8R8_SRGB: |
case PIPE_FORMAT_B8G8R8A8_SRGB: |
case PIPE_FORMAT_B8G8R8X8_SRGB: |
case PIPE_FORMAT_A8R8G8B8_SRGB: |
case PIPE_FORMAT_X8R8G8B8_SRGB: |
case PIPE_FORMAT_R8G8B8_SRGB: |
*datatype = DTYPE_UBYTE; |
*comps = 4; |
return; |
case PIPE_FORMAT_B5G5R5X1_UNORM: |
case PIPE_FORMAT_B5G5R5A1_UNORM: |
*datatype = DTYPE_USHORT_1_5_5_5_REV; |
*comps = 4; |
return; |
case PIPE_FORMAT_B4G4R4A4_UNORM: |
*datatype = DTYPE_USHORT_4_4_4_4; |
*comps = 4; |
return; |
case PIPE_FORMAT_B5G6R5_UNORM: |
*datatype = DTYPE_USHORT_5_6_5; |
*comps = 3; |
return; |
case PIPE_FORMAT_L8_UNORM: |
case PIPE_FORMAT_L8_SRGB: |
case PIPE_FORMAT_A8_UNORM: |
case PIPE_FORMAT_I8_UNORM: |
*datatype = DTYPE_UBYTE; |
*comps = 1; |
return; |
case PIPE_FORMAT_L8A8_UNORM: |
case PIPE_FORMAT_L8A8_SRGB: |
*datatype = DTYPE_UBYTE; |
*comps = 2; |
return; |
default: |
assert(0); |
*datatype = DTYPE_UBYTE; |
*comps = 0; |
break; |
} |
} |
static void |
reduce_1d(enum pipe_format pformat, |
int srcWidth, const ubyte *srcPtr, |
int dstWidth, ubyte *dstPtr) |
{ |
enum dtype datatype; |
uint comps; |
format_to_type_comps(pformat, &datatype, &comps); |
/* we just duplicate the input row, kind of hack, saves code */ |
do_row(datatype, comps, |
srcWidth, srcPtr, srcPtr, |
dstWidth, dstPtr); |
} |
/** |
* Strides are in bytes. If zero, it'll be computed as width * bpp. |
*/ |
static void |
reduce_2d(enum pipe_format pformat, |
int srcWidth, int srcHeight, |
int srcRowStride, const ubyte *srcPtr, |
int dstWidth, int dstHeight, |
int dstRowStride, ubyte *dstPtr) |
{ |
enum dtype datatype; |
uint comps; |
const int bpt = util_format_get_blocksize(pformat); |
const ubyte *srcA, *srcB; |
ubyte *dst; |
int row; |
format_to_type_comps(pformat, &datatype, &comps); |
if (!srcRowStride) |
srcRowStride = bpt * srcWidth; |
if (!dstRowStride) |
dstRowStride = bpt * dstWidth; |
/* Compute src and dst pointers */ |
srcA = srcPtr; |
if (srcHeight > 1) |
srcB = srcA + srcRowStride; |
else |
srcB = srcA; |
dst = dstPtr; |
for (row = 0; row < dstHeight; row++) { |
do_row(datatype, comps, |
srcWidth, srcA, srcB, |
dstWidth, dst); |
srcA += 2 * srcRowStride; |
srcB += 2 * srcRowStride; |
dst += dstRowStride; |
} |
} |
static void |
reduce_3d(enum pipe_format pformat, |
int srcWidth, int srcHeight, int srcDepth, |
int srcRowStride, int srcImageStride, const ubyte *srcPtr, |
int dstWidth, int dstHeight, int dstDepth, |
int dstRowStride, int dstImageStride, ubyte *dstPtr) |
{ |
const int bpt = util_format_get_blocksize(pformat); |
int img, row; |
int srcImageOffset, srcRowOffset; |
enum dtype datatype; |
uint comps; |
format_to_type_comps(pformat, &datatype, &comps); |
/* XXX I think we should rather assert those strides */ |
if (!srcImageStride) |
srcImageStride = srcWidth * srcHeight * bpt; |
if (!dstImageStride) |
dstImageStride = dstWidth * dstHeight * bpt; |
if (!srcRowStride) |
srcRowStride = srcWidth * bpt; |
if (!dstRowStride) |
dstRowStride = dstWidth * bpt; |
/* Offset between adjacent src images to be averaged together */ |
srcImageOffset = (srcDepth == dstDepth) ? 0 : srcImageStride; |
/* Offset between adjacent src rows to be averaged together */ |
srcRowOffset = (srcHeight == dstHeight) ? 0 : srcRowStride; |
/* |
* Need to average together up to 8 src pixels for each dest pixel. |
* Break that down into 3 operations: |
* 1. take two rows from source image and average them together. |
* 2. take two rows from next source image and average them together. |
* 3. take the two averaged rows and average them for the final dst row. |
*/ |
/* |
printf("mip3d %d x %d x %d -> %d x %d x %d\n", |
srcWidth, srcHeight, srcDepth, dstWidth, dstHeight, dstDepth); |
*/ |
for (img = 0; img < dstDepth; img++) { |
/* first source image pointer */ |
const ubyte *imgSrcA = srcPtr |
+ img * (srcImageStride + srcImageOffset); |
/* second source image pointer */ |
const ubyte *imgSrcB = imgSrcA + srcImageOffset; |
/* address of the dest image */ |
ubyte *imgDst = dstPtr + img * dstImageStride; |
/* setup the four source row pointers and the dest row pointer */ |
const ubyte *srcImgARowA = imgSrcA; |
const ubyte *srcImgARowB = imgSrcA + srcRowOffset; |
const ubyte *srcImgBRowA = imgSrcB; |
const ubyte *srcImgBRowB = imgSrcB + srcRowOffset; |
ubyte *dstImgRow = imgDst; |
for (row = 0; row < dstHeight; row++) { |
do_row_3D(datatype, comps, srcWidth, |
srcImgARowA, srcImgARowB, |
srcImgBRowA, srcImgBRowB, |
dstWidth, dstImgRow); |
/* advance to next rows */ |
srcImgARowA += srcRowStride + srcRowOffset; |
srcImgARowB += srcRowStride + srcRowOffset; |
srcImgBRowA += srcRowStride + srcRowOffset; |
srcImgBRowB += srcRowStride + srcRowOffset; |
dstImgRow += dstImageStride; |
} |
} |
} |
static void |
make_1d_mipmap(struct gen_mipmap_state *ctx, |
struct pipe_resource *pt, |
uint layer, uint baseLevel, uint lastLevel) |
{ |
struct pipe_context *pipe = ctx->pipe; |
uint dstLevel; |
for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) { |
const uint srcLevel = dstLevel - 1; |
struct pipe_transfer *srcTrans, *dstTrans; |
void *srcMap, *dstMap; |
srcMap = pipe_transfer_map(pipe, pt, srcLevel, layer, |
PIPE_TRANSFER_READ, 0, 0, |
u_minify(pt->width0, srcLevel), |
u_minify(pt->height0, srcLevel), &srcTrans); |
dstMap = pipe_transfer_map(pipe, pt, dstLevel, layer, |
PIPE_TRANSFER_WRITE, 0, 0, |
u_minify(pt->width0, dstLevel), |
u_minify(pt->height0, dstLevel), &dstTrans); |
reduce_1d(pt->format, |
srcTrans->box.width, srcMap, |
dstTrans->box.width, dstMap); |
pipe->transfer_unmap(pipe, srcTrans); |
pipe->transfer_unmap(pipe, dstTrans); |
} |
} |
static void |
make_2d_mipmap(struct gen_mipmap_state *ctx, |
struct pipe_resource *pt, |
uint layer, uint baseLevel, uint lastLevel) |
{ |
struct pipe_context *pipe = ctx->pipe; |
uint dstLevel; |
assert(util_format_get_blockwidth(pt->format) == 1); |
assert(util_format_get_blockheight(pt->format) == 1); |
for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) { |
const uint srcLevel = dstLevel - 1; |
struct pipe_transfer *srcTrans, *dstTrans; |
ubyte *srcMap, *dstMap; |
srcMap = pipe_transfer_map(pipe, pt, srcLevel, layer, |
PIPE_TRANSFER_READ, 0, 0, |
u_minify(pt->width0, srcLevel), |
u_minify(pt->height0, srcLevel), &srcTrans); |
dstMap = pipe_transfer_map(pipe, pt, dstLevel, layer, |
PIPE_TRANSFER_WRITE, 0, 0, |
u_minify(pt->width0, dstLevel), |
u_minify(pt->height0, dstLevel), &dstTrans); |
reduce_2d(pt->format, |
srcTrans->box.width, srcTrans->box.height, |
srcTrans->stride, srcMap, |
dstTrans->box.width, dstTrans->box.height, |
dstTrans->stride, dstMap); |
pipe->transfer_unmap(pipe, srcTrans); |
pipe->transfer_unmap(pipe, dstTrans); |
} |
} |
/* XXX looks a bit more like it could work now but need to test */ |
static void |
make_3d_mipmap(struct gen_mipmap_state *ctx, |
struct pipe_resource *pt, |
uint face, uint baseLevel, uint lastLevel) |
{ |
struct pipe_context *pipe = ctx->pipe; |
uint dstLevel; |
struct pipe_box src_box, dst_box; |
assert(util_format_get_blockwidth(pt->format) == 1); |
assert(util_format_get_blockheight(pt->format) == 1); |
src_box.x = src_box.y = src_box.z = 0; |
dst_box.x = dst_box.y = dst_box.z = 0; |
for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) { |
const uint srcLevel = dstLevel - 1; |
struct pipe_transfer *srcTrans, *dstTrans; |
ubyte *srcMap, *dstMap; |
struct pipe_box src_box, dst_box; |
src_box.width = u_minify(pt->width0, srcLevel); |
src_box.height = u_minify(pt->height0, srcLevel); |
src_box.depth = u_minify(pt->depth0, srcLevel); |
dst_box.width = u_minify(pt->width0, dstLevel); |
dst_box.height = u_minify(pt->height0, dstLevel); |
dst_box.depth = u_minify(pt->depth0, dstLevel); |
srcMap = pipe->transfer_map(pipe, pt, srcLevel, |
PIPE_TRANSFER_READ, |
&src_box, &srcTrans); |
dstMap = pipe->transfer_map(pipe, pt, dstLevel, |
PIPE_TRANSFER_WRITE, |
&dst_box, &dstTrans); |
reduce_3d(pt->format, |
srcTrans->box.width, srcTrans->box.height, srcTrans->box.depth, |
srcTrans->stride, srcTrans->layer_stride, srcMap, |
dstTrans->box.width, dstTrans->box.height, dstTrans->box.depth, |
dstTrans->stride, dstTrans->layer_stride, dstMap); |
pipe->transfer_unmap(pipe, srcTrans); |
pipe->transfer_unmap(pipe, dstTrans); |
} |
} |
static void |
fallback_gen_mipmap(struct gen_mipmap_state *ctx, |
struct pipe_resource *pt, |
uint layer, uint baseLevel, uint lastLevel) |
{ |
switch (pt->target) { |
case PIPE_TEXTURE_1D: |
make_1d_mipmap(ctx, pt, layer, baseLevel, lastLevel); |
break; |
case PIPE_TEXTURE_2D: |
case PIPE_TEXTURE_RECT: |
case PIPE_TEXTURE_CUBE: |
make_2d_mipmap(ctx, pt, layer, baseLevel, lastLevel); |
break; |
case PIPE_TEXTURE_3D: |
make_3d_mipmap(ctx, pt, layer, baseLevel, lastLevel); |
break; |
default: |
assert(0); |
} |
} |
/** |
* Create a mipmap generation context. |
* The idea is to create one of these and re-use it each time we need to |
* generate a mipmap. |
*/ |
struct gen_mipmap_state * |
util_create_gen_mipmap(struct pipe_context *pipe, |
struct cso_context *cso) |
{ |
struct gen_mipmap_state *ctx; |
uint i; |
ctx = CALLOC_STRUCT(gen_mipmap_state); |
if (!ctx) |
return NULL; |
ctx->pipe = pipe; |
ctx->cso = cso; |
/* disabled blending/masking */ |
memset(&ctx->blend_keep_color, 0, sizeof(ctx->blend_keep_color)); |
memset(&ctx->blend_write_color, 0, sizeof(ctx->blend_write_color)); |
ctx->blend_write_color.rt[0].colormask = PIPE_MASK_RGBA; |
/* no-op depth/stencil/alpha */ |
memset(&ctx->dsa_keep_depth, 0, sizeof(ctx->dsa_keep_depth)); |
memset(&ctx->dsa_write_depth, 0, sizeof(ctx->dsa_write_depth)); |
ctx->dsa_write_depth.depth.enabled = 1; |
ctx->dsa_write_depth.depth.func = PIPE_FUNC_ALWAYS; |
ctx->dsa_write_depth.depth.writemask = 1; |
/* rasterizer */ |
memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer)); |
ctx->rasterizer.cull_face = PIPE_FACE_NONE; |
ctx->rasterizer.half_pixel_center = 1; |
ctx->rasterizer.bottom_edge_rule = 1; |
ctx->rasterizer.depth_clip = 1; |
/* sampler state */ |
memset(&ctx->sampler, 0, sizeof(ctx->sampler)); |
ctx->sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; |
ctx->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; |
ctx->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; |
ctx->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST; |
ctx->sampler.normalized_coords = 1; |
/* vertex elements state */ |
memset(&ctx->velem[0], 0, sizeof(ctx->velem[0]) * 2); |
for (i = 0; i < 2; i++) { |
ctx->velem[i].src_offset = i * 4 * sizeof(float); |
ctx->velem[i].instance_divisor = 0; |
ctx->velem[i].vertex_buffer_index = cso_get_aux_vertex_buffer_slot(cso); |
ctx->velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT; |
} |
/* vertex data that doesn't change */ |
for (i = 0; i < 4; i++) { |
ctx->vertices[i][0][2] = 0.0f; /* z */ |
ctx->vertices[i][0][3] = 1.0f; /* w */ |
ctx->vertices[i][1][3] = 1.0f; /* q */ |
} |
/* Note: the actual vertex buffer is allocated as needed below */ |
return ctx; |
} |
/** |
* Helper function to set the fragment shaders. |
*/ |
static INLINE void |
set_fragment_shader(struct gen_mipmap_state *ctx, uint type, |
boolean output_depth) |
{ |
if (output_depth) { |
if (!ctx->fs_depth[type]) |
ctx->fs_depth[type] = |
util_make_fragment_tex_shader_writedepth(ctx->pipe, type, |
TGSI_INTERPOLATE_LINEAR); |
cso_set_fragment_shader_handle(ctx->cso, ctx->fs_depth[type]); |
} |
else { |
if (!ctx->fs_color[type]) |
ctx->fs_color[type] = |
util_make_fragment_tex_shader(ctx->pipe, type, |
TGSI_INTERPOLATE_LINEAR); |
cso_set_fragment_shader_handle(ctx->cso, ctx->fs_color[type]); |
} |
} |
/** |
* Helper function to set the vertex shader. |
*/ |
static INLINE void |
set_vertex_shader(struct gen_mipmap_state *ctx) |
{ |
/* vertex shader - still required to provide the linkage between |
* fragment shader input semantics and vertex_element/buffers. |
*/ |
if (!ctx->vs) |
{ |
const uint semantic_names[] = { TGSI_SEMANTIC_POSITION, |
TGSI_SEMANTIC_GENERIC }; |
const uint semantic_indexes[] = { 0, 0 }; |
ctx->vs = util_make_vertex_passthrough_shader(ctx->pipe, 2, |
semantic_names, |
semantic_indexes); |
} |
cso_set_vertex_shader_handle(ctx->cso, ctx->vs); |
} |
/** |
* Get next "slot" of vertex space in the vertex buffer. |
* We're allocating one large vertex buffer and using it piece by piece. |
*/ |
static unsigned |
get_next_slot(struct gen_mipmap_state *ctx) |
{ |
const unsigned max_slots = 4096 / sizeof ctx->vertices; |
if (ctx->vbuf_slot >= max_slots) { |
pipe_resource_reference(&ctx->vbuf, NULL); |
ctx->vbuf_slot = 0; |
} |
if (!ctx->vbuf) { |
ctx->vbuf = pipe_buffer_create(ctx->pipe->screen, |
PIPE_BIND_VERTEX_BUFFER, |
PIPE_USAGE_STREAM, |
max_slots * sizeof ctx->vertices); |
} |
return ctx->vbuf_slot++ * sizeof ctx->vertices; |
} |
static unsigned |
set_vertex_data(struct gen_mipmap_state *ctx, |
enum pipe_texture_target tex_target, |
uint layer, float r) |
{ |
unsigned offset; |
/* vert[0].position */ |
ctx->vertices[0][0][0] = -1.0f; /*x*/ |
ctx->vertices[0][0][1] = -1.0f; /*y*/ |
/* vert[1].position */ |
ctx->vertices[1][0][0] = 1.0f; |
ctx->vertices[1][0][1] = -1.0f; |
/* vert[2].position */ |
ctx->vertices[2][0][0] = 1.0f; |
ctx->vertices[2][0][1] = 1.0f; |
/* vert[3].position */ |
ctx->vertices[3][0][0] = -1.0f; |
ctx->vertices[3][0][1] = 1.0f; |
/* Setup vertex texcoords. This is a little tricky for cube maps. */ |
if (tex_target == PIPE_TEXTURE_CUBE) { |
static const float st[4][2] = { |
{0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f} |
}; |
util_map_texcoords2d_onto_cubemap(layer, &st[0][0], 2, |
&ctx->vertices[0][1][0], 8); |
} |
else if (tex_target == PIPE_TEXTURE_1D_ARRAY) { |
/* 1D texture array */ |
ctx->vertices[0][1][0] = 0.0f; /*s*/ |
ctx->vertices[0][1][1] = r; /*t*/ |
ctx->vertices[0][1][2] = 0.0f; /*r*/ |
ctx->vertices[1][1][0] = 1.0f; |
ctx->vertices[1][1][1] = r; |
ctx->vertices[1][1][2] = 0.0f; |
ctx->vertices[2][1][0] = 1.0f; |
ctx->vertices[2][1][1] = r; |
ctx->vertices[2][1][2] = 0.0f; |
ctx->vertices[3][1][0] = 0.0f; |
ctx->vertices[3][1][1] = r; |
ctx->vertices[3][1][2] = 0.0f; |
} else { |
/* 1D/2D/3D/2D array */ |
ctx->vertices[0][1][0] = 0.0f; /*s*/ |
ctx->vertices[0][1][1] = 0.0f; /*t*/ |
ctx->vertices[0][1][2] = r; /*r*/ |
ctx->vertices[1][1][0] = 1.0f; |
ctx->vertices[1][1][1] = 0.0f; |
ctx->vertices[1][1][2] = r; |
ctx->vertices[2][1][0] = 1.0f; |
ctx->vertices[2][1][1] = 1.0f; |
ctx->vertices[2][1][2] = r; |
ctx->vertices[3][1][0] = 0.0f; |
ctx->vertices[3][1][1] = 1.0f; |
ctx->vertices[3][1][2] = r; |
} |
offset = get_next_slot( ctx ); |
pipe_buffer_write_nooverlap(ctx->pipe, ctx->vbuf, |
offset, sizeof(ctx->vertices), ctx->vertices); |
return offset; |
} |
/** |
* Destroy a mipmap generation context |
*/ |
void |
util_destroy_gen_mipmap(struct gen_mipmap_state *ctx) |
{ |
struct pipe_context *pipe = ctx->pipe; |
unsigned i; |
for (i = 0; i < Elements(ctx->fs_color); i++) |
if (ctx->fs_color[i]) |
pipe->delete_fs_state(pipe, ctx->fs_color[i]); |
for (i = 0; i < Elements(ctx->fs_depth); i++) |
if (ctx->fs_depth[i]) |
pipe->delete_fs_state(pipe, ctx->fs_depth[i]); |
if (ctx->vs) |
pipe->delete_vs_state(pipe, ctx->vs); |
pipe_resource_reference(&ctx->vbuf, NULL); |
FREE(ctx); |
} |
/** |
* Generate mipmap images. It's assumed all needed texture memory is |
* already allocated. |
* |
* \param psv the sampler view to the texture to generate mipmap levels for |
* \param face which cube face to generate mipmaps for (0 for non-cube maps) |
* \param baseLevel the first mipmap level to use as a src |
* \param lastLevel the last mipmap level to generate |
* \param filter the minification filter used to generate mipmap levels with |
* \param filter one of PIPE_TEX_FILTER_LINEAR, PIPE_TEX_FILTER_NEAREST |
*/ |
void |
util_gen_mipmap(struct gen_mipmap_state *ctx, |
struct pipe_sampler_view *psv, |
uint face, uint baseLevel, uint lastLevel, uint filter) |
{ |
struct pipe_context *pipe = ctx->pipe; |
struct pipe_screen *screen = pipe->screen; |
struct pipe_framebuffer_state fb; |
struct pipe_resource *pt = psv->texture; |
uint dstLevel; |
uint offset; |
uint type; |
boolean is_depth = util_format_is_depth_or_stencil(psv->format); |
/* The texture object should have room for the levels which we're |
* about to generate. |
*/ |
assert(lastLevel <= pt->last_level); |
/* If this fails, why are we here? */ |
assert(lastLevel > baseLevel); |
assert(filter == PIPE_TEX_FILTER_LINEAR || |
filter == PIPE_TEX_FILTER_NEAREST); |
switch (pt->target) { |
case PIPE_TEXTURE_1D: |
type = TGSI_TEXTURE_1D; |
break; |
case PIPE_TEXTURE_2D: |
type = TGSI_TEXTURE_2D; |
break; |
case PIPE_TEXTURE_3D: |
type = TGSI_TEXTURE_3D; |
break; |
case PIPE_TEXTURE_CUBE: |
type = TGSI_TEXTURE_CUBE; |
break; |
case PIPE_TEXTURE_1D_ARRAY: |
type = TGSI_TEXTURE_1D_ARRAY; |
break; |
case PIPE_TEXTURE_2D_ARRAY: |
type = TGSI_TEXTURE_2D_ARRAY; |
break; |
default: |
assert(0); |
type = TGSI_TEXTURE_2D; |
} |
/* check if we can render in the texture's format */ |
if (!screen->is_format_supported(screen, psv->format, pt->target, |
pt->nr_samples, |
is_depth ? PIPE_BIND_DEPTH_STENCIL : |
PIPE_BIND_RENDER_TARGET)) { |
fallback_gen_mipmap(ctx, pt, face, baseLevel, lastLevel); |
return; |
} |
/* save state (restored below) */ |
cso_save_blend(ctx->cso); |
cso_save_depth_stencil_alpha(ctx->cso); |
cso_save_rasterizer(ctx->cso); |
cso_save_sample_mask(ctx->cso); |
cso_save_samplers(ctx->cso, PIPE_SHADER_FRAGMENT); |
cso_save_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT); |
cso_save_stream_outputs(ctx->cso); |
cso_save_framebuffer(ctx->cso); |
cso_save_fragment_shader(ctx->cso); |
cso_save_vertex_shader(ctx->cso); |
cso_save_geometry_shader(ctx->cso); |
cso_save_viewport(ctx->cso); |
cso_save_vertex_elements(ctx->cso); |
cso_save_aux_vertex_buffer_slot(ctx->cso); |
cso_save_render_condition(ctx->cso); |
/* bind our state */ |
cso_set_blend(ctx->cso, is_depth ? &ctx->blend_keep_color : |
&ctx->blend_write_color); |
cso_set_depth_stencil_alpha(ctx->cso, is_depth ? &ctx->dsa_write_depth : |
&ctx->dsa_keep_depth); |
cso_set_rasterizer(ctx->cso, &ctx->rasterizer); |
cso_set_sample_mask(ctx->cso, ~0); |
cso_set_vertex_elements(ctx->cso, 2, ctx->velem); |
cso_set_stream_outputs(ctx->cso, 0, NULL, 0); |
cso_set_render_condition(ctx->cso, NULL, FALSE, 0); |
set_fragment_shader(ctx, type, is_depth); |
set_vertex_shader(ctx); |
cso_set_geometry_shader_handle(ctx->cso, NULL); |
/* init framebuffer state */ |
memset(&fb, 0, sizeof(fb)); |
/* set min/mag to same filter for faster sw speed */ |
ctx->sampler.mag_img_filter = filter; |
ctx->sampler.min_img_filter = filter; |
for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) { |
const uint srcLevel = dstLevel - 1; |
struct pipe_viewport_state vp; |
unsigned nr_layers, layer, i; |
float rcoord = 0.0f; |
if (pt->target == PIPE_TEXTURE_3D) |
nr_layers = u_minify(pt->depth0, dstLevel); |
else if (pt->target == PIPE_TEXTURE_2D_ARRAY || pt->target == PIPE_TEXTURE_1D_ARRAY) |
nr_layers = pt->array_size; |
else |
nr_layers = 1; |
for (i = 0; i < nr_layers; i++) { |
struct pipe_surface *surf, surf_templ; |
if (pt->target == PIPE_TEXTURE_3D) { |
/* in theory with geom shaders and driver with full layer support |
could do that in one go. */ |
layer = i; |
/* XXX hmm really? */ |
rcoord = (float)layer / (float)nr_layers + 1.0f / (float)(nr_layers * 2); |
} else if (pt->target == PIPE_TEXTURE_2D_ARRAY || pt->target == PIPE_TEXTURE_1D_ARRAY) { |
layer = i; |
rcoord = (float)layer; |
} else |
layer = face; |
u_surface_default_template(&surf_templ, pt); |
surf_templ.u.tex.level = dstLevel; |
surf_templ.u.tex.first_layer = layer; |
surf_templ.u.tex.last_layer = layer; |
surf = pipe->create_surface(pipe, pt, &surf_templ); |
/* |
* Setup framebuffer / dest surface |
*/ |
if (is_depth) { |
fb.nr_cbufs = 0; |
fb.zsbuf = surf; |
} |
else { |
fb.nr_cbufs = 1; |
fb.cbufs[0] = surf; |
} |
fb.width = u_minify(pt->width0, dstLevel); |
fb.height = u_minify(pt->height0, dstLevel); |
cso_set_framebuffer(ctx->cso, &fb); |
/* viewport */ |
vp.scale[0] = 0.5f * fb.width; |
vp.scale[1] = 0.5f * fb.height; |
vp.scale[2] = 1.0f; |
vp.scale[3] = 1.0f; |
vp.translate[0] = 0.5f * fb.width; |
vp.translate[1] = 0.5f * fb.height; |
vp.translate[2] = 0.0f; |
vp.translate[3] = 0.0f; |
cso_set_viewport(ctx->cso, &vp); |
/* |
* Setup sampler state |
* Note: we should only have to set the min/max LOD clamps to ensure |
* we grab texels from the right mipmap level. But some hardware |
* has trouble with min clamping so we also set the lod_bias to |
* try to work around that. |
*/ |
ctx->sampler.min_lod = ctx->sampler.max_lod = (float) srcLevel; |
ctx->sampler.lod_bias = (float) srcLevel; |
cso_single_sampler(ctx->cso, PIPE_SHADER_FRAGMENT, 0, &ctx->sampler); |
cso_single_sampler_done(ctx->cso, PIPE_SHADER_FRAGMENT); |
cso_set_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT, 1, &psv); |
/* quad coords in clip coords */ |
offset = set_vertex_data(ctx, |
pt->target, |
face, |
rcoord); |
util_draw_vertex_buffer(ctx->pipe, |
ctx->cso, |
ctx->vbuf, |
cso_get_aux_vertex_buffer_slot(ctx->cso), |
offset, |
PIPE_PRIM_TRIANGLE_FAN, |
4, /* verts */ |
2); /* attribs/vert */ |
/* need to signal that the texture has changed _after_ rendering to it */ |
pipe_surface_reference( &surf, NULL ); |
} |
} |
/* restore state we changed */ |
cso_restore_blend(ctx->cso); |
cso_restore_depth_stencil_alpha(ctx->cso); |
cso_restore_rasterizer(ctx->cso); |
cso_restore_sample_mask(ctx->cso); |
cso_restore_samplers(ctx->cso, PIPE_SHADER_FRAGMENT); |
cso_restore_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT); |
cso_restore_framebuffer(ctx->cso); |
cso_restore_fragment_shader(ctx->cso); |
cso_restore_vertex_shader(ctx->cso); |
cso_restore_geometry_shader(ctx->cso); |
cso_restore_viewport(ctx->cso); |
cso_restore_vertex_elements(ctx->cso); |
cso_restore_stream_outputs(ctx->cso); |
cso_restore_aux_vertex_buffer_slot(ctx->cso); |
cso_restore_render_condition(ctx->cso); |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_gen_mipmap.h |
---|
0,0 → 1,64 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* 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 TUNGSTEN GRAPHICS 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_GENMIPMAP_H |
#define U_GENMIPMAP_H |
#include "pipe/p_state.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
struct pipe_context; |
struct pipe_resource; |
struct cso_context; |
struct gen_mipmap_state; |
extern struct gen_mipmap_state * |
util_create_gen_mipmap(struct pipe_context *pipe, struct cso_context *cso); |
extern void |
util_destroy_gen_mipmap(struct gen_mipmap_state *ctx); |
extern void |
util_gen_mipmap(struct gen_mipmap_state *ctx, |
struct pipe_sampler_view *psv, |
uint layer, uint baseLevel, uint lastLevel, uint filter); |
#ifdef __cplusplus |
} |
#endif |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_half.h |
---|
0,0 → 1,123 |
/************************************************************************** |
* |
* Copyright 2010 Luca Barbieri |
* |
* 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, sublicense, 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 NONINFRINGEMENT. |
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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_HALF_H |
#define U_HALF_H |
#include "pipe/p_compiler.h" |
#include "util/u_math.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
/* |
* References for float <-> half conversions |
* |
* http://fgiesen.wordpress.com/2012/03/28/half-to-float-done-quic/ |
* https://gist.github.com/2156668 |
* https://gist.github.com/2144712 |
*/ |
static INLINE uint16_t |
util_float_to_half(float f) |
{ |
uint32_t sign_mask = 0x80000000; |
uint32_t round_mask = ~0xfff; |
uint32_t f32inf = 0xff << 23; |
uint32_t f16inf = 0x1f << 23; |
uint32_t sign; |
union fi magic; |
union fi f32; |
uint16_t f16; |
magic.ui = 0xf << 23; |
f32.f = f; |
/* Sign */ |
sign = f32.ui & sign_mask; |
f32.ui ^= sign; |
if (f32.ui == f32inf) { |
/* Inf */ |
f16 = 0x7c00; |
} else if (f32.ui > f32inf) { |
/* NaN */ |
f16 = 0x7e00; |
} else { |
/* Number */ |
f32.ui &= round_mask; |
f32.f *= magic.f; |
f32.ui -= round_mask; |
/* Clamp to infinity if overflowed */ |
if (f32.ui > f16inf) |
f32.ui = f16inf; |
f16 = f32.ui >> 13; |
} |
/* Sign */ |
f16 |= sign >> 16; |
return f16; |
} |
static INLINE float |
util_half_to_float(uint16_t f16) |
{ |
union fi infnan; |
union fi magic; |
union fi f32; |
infnan.ui = 0x8f << 23; |
infnan.f = 65536.0f; |
magic.ui = 0xef << 23; |
/* Exponent / Mantissa */ |
f32.ui = (f16 & 0x7fff) << 13; |
/* Adjust */ |
f32.f *= magic.f; |
/* Inf / NaN */ |
if (f32.f >= infnan.f) |
f32.ui |= 0xff << 23; |
/* Sign */ |
f32.ui |= (f16 & 0x8000) << 16; |
return f32.f; |
} |
#ifdef __cplusplus |
} |
#endif |
#endif /* U_HALF_H */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_handle_table.c |
---|
0,0 → 1,298 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* 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 TUNGSTEN GRAPHICS 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. |
* |
**************************************************************************/ |
/** |
* @file |
* Generic handle table implementation. |
* |
* @author José Fonseca <jrfonseca@tungstengraphics.com> |
*/ |
#include "pipe/p_compiler.h" |
#include "util/u_debug.h" |
#include "util/u_memory.h" |
#include "util/u_handle_table.h" |
#define HANDLE_TABLE_INITIAL_SIZE 16 |
struct handle_table |
{ |
/** Object array. Empty handles have a null object */ |
void **objects; |
/** Number of objects the handle can currently hold */ |
unsigned size; |
/** Number of consecutive objects allocated at the start of the table */ |
unsigned filled; |
/** Optional object destructor */ |
void (*destroy)(void *object); |
}; |
struct handle_table * |
handle_table_create(void) |
{ |
struct handle_table *ht; |
ht = MALLOC_STRUCT(handle_table); |
if(!ht) |
return NULL; |
ht->objects = (void **)CALLOC(HANDLE_TABLE_INITIAL_SIZE, sizeof(void *)); |
if(!ht->objects) { |
FREE(ht); |
return NULL; |
} |
ht->size = HANDLE_TABLE_INITIAL_SIZE; |
ht->filled = 0; |
ht->destroy = NULL; |
return ht; |
} |
void |
handle_table_set_destroy(struct handle_table *ht, |
void (*destroy)(void *object)) |
{ |
assert(ht); |
if (!ht) |
return; |
ht->destroy = destroy; |
} |
/** |
* Resize the table if necessary |
*/ |
static INLINE int |
handle_table_resize(struct handle_table *ht, |
unsigned minimum_size) |
{ |
unsigned new_size; |
void **new_objects; |
if(ht->size > minimum_size) |
return ht->size; |
new_size = ht->size; |
while(!(new_size > minimum_size)) |
new_size *= 2; |
assert(new_size); |
new_objects = (void **)REALLOC((void *)ht->objects, |
ht->size*sizeof(void *), |
new_size*sizeof(void *)); |
if(!new_objects) |
return 0; |
memset(new_objects + ht->size, 0, (new_size - ht->size)*sizeof(void *)); |
ht->size = new_size; |
ht->objects = new_objects; |
return ht->size; |
} |
static INLINE void |
handle_table_clear(struct handle_table *ht, |
unsigned index) |
{ |
void *object; |
/* The order here is important so that the object being destroyed is not |
* present in the table when seen by the destroy callback, because the |
* destroy callback may directly or indirectly call the other functions in |
* this module. |
*/ |
object = ht->objects[index]; |
if(object) { |
ht->objects[index] = NULL; |
if(ht->destroy) |
ht->destroy(object); |
} |
} |
unsigned |
handle_table_add(struct handle_table *ht, |
void *object) |
{ |
unsigned index; |
unsigned handle; |
assert(ht); |
assert(object); |
if(!object || !ht) |
return 0; |
/* linear search for an empty handle */ |
while(ht->filled < ht->size) { |
if(!ht->objects[ht->filled]) |
break; |
++ht->filled; |
} |
index = ht->filled; |
handle = index + 1; |
/* check integer overflow */ |
if(!handle) |
return 0; |
/* grow the table if necessary */ |
if(!handle_table_resize(ht, index)) |
return 0; |
assert(!ht->objects[index]); |
ht->objects[index] = object; |
++ht->filled; |
return handle; |
} |
unsigned |
handle_table_set(struct handle_table *ht, |
unsigned handle, |
void *object) |
{ |
unsigned index; |
assert(ht); |
assert(handle); |
if(!handle || !ht) |
return 0; |
assert(object); |
if(!object) |
return 0; |
index = handle - 1; |
/* grow the table if necessary */ |
if(!handle_table_resize(ht, index)) |
return 0; |
handle_table_clear(ht, index); |
ht->objects[index] = object; |
return handle; |
} |
void * |
handle_table_get(struct handle_table *ht, |
unsigned handle) |
{ |
void *object; |
assert(ht); |
assert(handle); |
if(!handle || !ht || handle > ht->size) |
return NULL; |
object = ht->objects[handle - 1]; |
return object; |
} |
void |
handle_table_remove(struct handle_table *ht, |
unsigned handle) |
{ |
void *object; |
unsigned index; |
assert(ht); |
assert(handle); |
if(!handle || !ht || handle > ht->size) |
return; |
index = handle - 1; |
object = ht->objects[index]; |
if(!object) |
return; |
handle_table_clear(ht, index); |
if(index < ht->filled) |
ht->filled = index; |
} |
unsigned |
handle_table_get_next_handle(struct handle_table *ht, |
unsigned handle) |
{ |
unsigned index; |
for(index = handle; index < ht->size; ++index) { |
if(ht->objects[index]) |
return index + 1; |
} |
return 0; |
} |
unsigned |
handle_table_get_first_handle(struct handle_table *ht) |
{ |
return handle_table_get_next_handle(ht, 0); |
} |
void |
handle_table_destroy(struct handle_table *ht) |
{ |
unsigned index; |
assert(ht); |
if (!ht) |
return; |
if(ht->destroy) |
for(index = 0; index < ht->size; ++index) |
handle_table_clear(ht, index); |
FREE(ht->objects); |
FREE(ht); |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_handle_table.h |
---|
0,0 → 1,116 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* 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 TUNGSTEN GRAPHICS 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. |
* |
**************************************************************************/ |
/** |
* @file |
* Generic handle table. |
* |
* @author José Fonseca <jrfonseca@tungstengraphics.com> |
*/ |
#ifndef U_HANDLE_TABLE_H_ |
#define U_HANDLE_TABLE_H_ |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* Abstract data type to map integer handles to objects. |
* |
* Also referred as "pointer array". |
*/ |
struct handle_table; |
struct handle_table * |
handle_table_create(void); |
/** |
* Set an optional destructor callback. |
* |
* If set, it will be called during handle_table_remove and |
* handle_table_destroy calls. |
*/ |
void |
handle_table_set_destroy(struct handle_table *ht, |
void (*destroy)(void *object)); |
/** |
* Add a new object. |
* |
* Returns a zero handle on failure (out of memory). |
*/ |
unsigned |
handle_table_add(struct handle_table *ht, |
void *object); |
/** |
* Returns zero on failure (out of memory). |
*/ |
unsigned |
handle_table_set(struct handle_table *ht, |
unsigned handle, |
void *object); |
/** |
* Fetch an existing object. |
* |
* Returns NULL for an invalid handle. |
*/ |
void * |
handle_table_get(struct handle_table *ht, |
unsigned handle); |
void |
handle_table_remove(struct handle_table *ht, |
unsigned handle); |
void |
handle_table_destroy(struct handle_table *ht); |
unsigned |
handle_table_get_first_handle(struct handle_table *ht); |
unsigned |
handle_table_get_next_handle(struct handle_table *ht, |
unsigned handle); |
#ifdef __cplusplus |
} |
#endif |
#endif /* U_HANDLE_TABLE_H_ */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_hash.c |
---|
0,0 → 1,121 |
/************************************************************************** |
* |
* Copyright 2008 VMware, Inc. |
* 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 VMWARE 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. |
* |
**************************************************************************/ |
/** |
* @file |
* Hash functions implementation. |
* |
* @author Jose Fonseca |
*/ |
#include "u_hash.h" |
static const uint32_t |
util_crc32_table[256] = { |
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, |
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, |
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, |
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, |
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, |
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, |
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, |
0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, |
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, |
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, |
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, |
0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, |
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, |
0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, |
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, |
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, |
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, |
0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, |
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, |
0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, |
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, |
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, |
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, |
0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, |
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, |
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, |
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, |
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, |
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, |
0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, |
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, |
0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, |
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, |
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, |
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, |
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, |
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, |
0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, |
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, |
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, |
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, |
0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, |
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, |
0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, |
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, |
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, |
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, |
0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, |
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, |
0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, |
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, |
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, |
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, |
0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, |
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, |
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, |
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, |
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, |
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, |
0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, |
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, |
0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, |
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, |
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d |
}; |
/** |
* @sa http://www.w3.org/TR/PNG/#D-CRCAppendix |
*/ |
uint32_t |
util_hash_crc32(const void *data, size_t size) |
{ |
uint8_t *p = (uint8_t *)data; |
uint32_t crc = 0xffffffff; |
while (size--) |
crc = util_crc32_table[(crc ^ *p++) & 0xff] ^ (crc >> 8); |
return crc; |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_hash.h |
---|
0,0 → 1,55 |
/************************************************************************** |
* |
* Copyright 2008 VMware, Inc. |
* 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 VMWARE 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. |
* |
**************************************************************************/ |
/** |
* @file |
* Hash functions. |
* |
* @author Jose Fonseca <jfonseca@vmware.com> |
*/ |
#ifndef U_HASH_H_ |
#define U_HASH_H_ |
#include "pipe/p_compiler.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
uint32_t |
util_hash_crc32(const void *data, size_t size); |
#ifdef __cplusplus |
} |
#endif |
#endif /* U_HASH_H_ */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_hash_table.c |
---|
0,0 → 1,293 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* 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 TUNGSTEN GRAPHICS 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. |
* |
**************************************************************************/ |
/** |
* @file |
* General purpose hash table implementation. |
* |
* Just uses the cso_hash for now, but it might be better switch to a linear |
* probing hash table implementation at some point -- as it is said they have |
* better lookup and cache performance and it appears to be possible to write |
* a lock-free implementation of such hash tables . |
* |
* @author José Fonseca <jrfonseca@tungstengraphics.com> |
*/ |
#include "pipe/p_compiler.h" |
#include "util/u_debug.h" |
#include "cso_cache/cso_hash.h" |
#include "util/u_memory.h" |
#include "util/u_hash_table.h" |
struct util_hash_table |
{ |
struct cso_hash *cso; |
/** Hash function */ |
unsigned (*hash)(void *key); |
/** Compare two keys */ |
int (*compare)(void *key1, void *key2); |
/* TODO: key, value destructors? */ |
}; |
struct util_hash_table_item |
{ |
void *key; |
void *value; |
}; |
static INLINE struct util_hash_table_item * |
util_hash_table_item(struct cso_hash_iter iter) |
{ |
return (struct util_hash_table_item *)cso_hash_iter_data(iter); |
} |
struct util_hash_table * |
util_hash_table_create(unsigned (*hash)(void *key), |
int (*compare)(void *key1, void *key2)) |
{ |
struct util_hash_table *ht; |
ht = MALLOC_STRUCT(util_hash_table); |
if(!ht) |
return NULL; |
ht->cso = cso_hash_create(); |
if(!ht->cso) { |
FREE(ht); |
return NULL; |
} |
ht->hash = hash; |
ht->compare = compare; |
return ht; |
} |
static INLINE struct cso_hash_iter |
util_hash_table_find_iter(struct util_hash_table *ht, |
void *key, |
unsigned key_hash) |
{ |
struct cso_hash_iter iter; |
struct util_hash_table_item *item; |
iter = cso_hash_find(ht->cso, key_hash); |
while (!cso_hash_iter_is_null(iter)) { |
item = (struct util_hash_table_item *)cso_hash_iter_data(iter); |
if (!ht->compare(item->key, key)) |
break; |
iter = cso_hash_iter_next(iter); |
} |
return iter; |
} |
static INLINE struct util_hash_table_item * |
util_hash_table_find_item(struct util_hash_table *ht, |
void *key, |
unsigned key_hash) |
{ |
struct cso_hash_iter iter; |
struct util_hash_table_item *item; |
iter = cso_hash_find(ht->cso, key_hash); |
while (!cso_hash_iter_is_null(iter)) { |
item = (struct util_hash_table_item *)cso_hash_iter_data(iter); |
if (!ht->compare(item->key, key)) |
return item; |
iter = cso_hash_iter_next(iter); |
} |
return NULL; |
} |
enum pipe_error |
util_hash_table_set(struct util_hash_table *ht, |
void *key, |
void *value) |
{ |
unsigned key_hash; |
struct util_hash_table_item *item; |
struct cso_hash_iter iter; |
assert(ht); |
if (!ht) |
return PIPE_ERROR_BAD_INPUT; |
key_hash = ht->hash(key); |
item = util_hash_table_find_item(ht, key, key_hash); |
if(item) { |
/* TODO: key/value destruction? */ |
item->value = value; |
return PIPE_OK; |
} |
item = MALLOC_STRUCT(util_hash_table_item); |
if(!item) |
return PIPE_ERROR_OUT_OF_MEMORY; |
item->key = key; |
item->value = value; |
iter = cso_hash_insert(ht->cso, key_hash, item); |
if(cso_hash_iter_is_null(iter)) { |
FREE(item); |
return PIPE_ERROR_OUT_OF_MEMORY; |
} |
return PIPE_OK; |
} |
void * |
util_hash_table_get(struct util_hash_table *ht, |
void *key) |
{ |
unsigned key_hash; |
struct util_hash_table_item *item; |
assert(ht); |
if (!ht) |
return NULL; |
key_hash = ht->hash(key); |
item = util_hash_table_find_item(ht, key, key_hash); |
if(!item) |
return NULL; |
return item->value; |
} |
void |
util_hash_table_remove(struct util_hash_table *ht, |
void *key) |
{ |
unsigned key_hash; |
struct cso_hash_iter iter; |
struct util_hash_table_item *item; |
assert(ht); |
if (!ht) |
return; |
key_hash = ht->hash(key); |
iter = util_hash_table_find_iter(ht, key, key_hash); |
if(cso_hash_iter_is_null(iter)) |
return; |
item = util_hash_table_item(iter); |
assert(item); |
FREE(item); |
cso_hash_erase(ht->cso, iter); |
} |
void |
util_hash_table_clear(struct util_hash_table *ht) |
{ |
struct cso_hash_iter iter; |
struct util_hash_table_item *item; |
assert(ht); |
if (!ht) |
return; |
iter = cso_hash_first_node(ht->cso); |
while (!cso_hash_iter_is_null(iter)) { |
item = (struct util_hash_table_item *)cso_hash_take(ht->cso, cso_hash_iter_key(iter)); |
FREE(item); |
iter = cso_hash_first_node(ht->cso); |
} |
} |
enum pipe_error |
util_hash_table_foreach(struct util_hash_table *ht, |
enum pipe_error (*callback) |
(void *key, void *value, void *data), |
void *data) |
{ |
struct cso_hash_iter iter; |
struct util_hash_table_item *item; |
enum pipe_error result; |
assert(ht); |
if (!ht) |
return PIPE_ERROR_BAD_INPUT; |
iter = cso_hash_first_node(ht->cso); |
while (!cso_hash_iter_is_null(iter)) { |
item = (struct util_hash_table_item *)cso_hash_iter_data(iter); |
result = callback(item->key, item->value, data); |
if(result != PIPE_OK) |
return result; |
iter = cso_hash_iter_next(iter); |
} |
return PIPE_OK; |
} |
void |
util_hash_table_destroy(struct util_hash_table *ht) |
{ |
struct cso_hash_iter iter; |
struct util_hash_table_item *item; |
assert(ht); |
if (!ht) |
return; |
iter = cso_hash_first_node(ht->cso); |
while (!cso_hash_iter_is_null(iter)) { |
item = (struct util_hash_table_item *)cso_hash_iter_data(iter); |
FREE(item); |
iter = cso_hash_iter_next(iter); |
} |
cso_hash_delete(ht->cso); |
FREE(ht); |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_hash_table.h |
---|
0,0 → 1,96 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* 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 TUNGSTEN GRAPHICS 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. |
* |
**************************************************************************/ |
/** |
* General purpose hash table. |
* |
* @author José Fonseca <jrfonseca@tungstengraphics.com> |
*/ |
#ifndef U_HASH_TABLE_H_ |
#define U_HASH_TABLE_H_ |
#include "pipe/p_defines.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* Generic purpose hash table. |
*/ |
struct util_hash_table; |
/** |
* Create an hash table. |
* |
* @param hash hash function |
* @param compare should return 0 for two equal keys. |
*/ |
struct util_hash_table * |
util_hash_table_create(unsigned (*hash)(void *key), |
int (*compare)(void *key1, void *key2)); |
enum pipe_error |
util_hash_table_set(struct util_hash_table *ht, |
void *key, |
void *value); |
void * |
util_hash_table_get(struct util_hash_table *ht, |
void *key); |
void |
util_hash_table_remove(struct util_hash_table *ht, |
void *key); |
void |
util_hash_table_clear(struct util_hash_table *ht); |
enum pipe_error |
util_hash_table_foreach(struct util_hash_table *ht, |
enum pipe_error (*callback) |
(void *key, void *value, void *data), |
void *data); |
void |
util_hash_table_destroy(struct util_hash_table *ht); |
#ifdef __cplusplus |
} |
#endif |
#endif /* U_HASH_TABLE_H_ */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_helpers.c |
---|
0,0 → 1,90 |
/************************************************************************** |
* |
* Copyright 2012 Marek Olšák <maraeo@gmail.com> |
* 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 THE AUTHORS AND/OR THEIR 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_helpers.h" |
#include "util/u_inlines.h" |
/** |
* This function is used to copy an array of pipe_vertex_buffer structures, |
* while properly referencing the pipe_vertex_buffer::buffer member. |
* |
* enabled_buffers is updated such that the bits corresponding to the indices |
* of disabled buffers are set to 0 and the enabled ones are set to 1. |
* |
* \sa util_copy_framebuffer_state |
*/ |
void util_set_vertex_buffers_mask(struct pipe_vertex_buffer *dst, |
uint32_t *enabled_buffers, |
const struct pipe_vertex_buffer *src, |
unsigned start_slot, unsigned count) |
{ |
unsigned i; |
uint32_t bitmask = 0; |
dst += start_slot; |
if (src) { |
for (i = 0; i < count; i++) { |
if (src[i].buffer || src[i].user_buffer) { |
bitmask |= 1 << i; |
} |
pipe_resource_reference(&dst[i].buffer, src[i].buffer); |
} |
/* Copy over the other members of pipe_vertex_buffer. */ |
memcpy(dst, src, count * sizeof(struct pipe_vertex_buffer)); |
*enabled_buffers &= ~(((1ull << count) - 1) << start_slot); |
*enabled_buffers |= bitmask << start_slot; |
} |
else { |
/* Unreference the buffers. */ |
for (i = 0; i < count; i++) { |
pipe_resource_reference(&dst[i].buffer, NULL); |
dst[i].user_buffer = NULL; |
} |
*enabled_buffers &= ~(((1ull << count) - 1) << start_slot); |
} |
} |
/** |
* Same as util_set_vertex_buffers_mask, but it only returns the number |
* of bound buffers. |
*/ |
void util_set_vertex_buffers_count(struct pipe_vertex_buffer *dst, |
unsigned *dst_count, |
const struct pipe_vertex_buffer *src, |
unsigned start_slot, unsigned count) |
{ |
uint32_t enabled_buffers = (1ull << *dst_count) - 1; |
util_set_vertex_buffers_mask(dst, &enabled_buffers, src, start_slot, |
count); |
*dst_count = util_last_bit(enabled_buffers); |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_helpers.h |
---|
0,0 → 1,51 |
/************************************************************************** |
* |
* Copyright 2012 Marek Olšák <maraeo@gmail.com> |
* 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 THE AUTHORS AND/OR THEIR 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_HELPERS_H |
#define U_HELPERS_H |
#ifdef __cplusplus |
extern "C" { |
#endif |
#include "pipe/p_state.h" |
void util_set_vertex_buffers_mask(struct pipe_vertex_buffer *dst, |
uint32_t *enabled_buffers, |
const struct pipe_vertex_buffer *src, |
unsigned start_slot, unsigned count); |
void util_set_vertex_buffers_count(struct pipe_vertex_buffer *dst, |
unsigned *dst_count, |
const struct pipe_vertex_buffer *src, |
unsigned start_slot, unsigned count); |
#ifdef __cplusplus |
} |
#endif |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_index_modify.c |
---|
0,0 → 1,203 |
/* |
* Copyright 2010 Marek Olšák <maraeo@gmail.com> |
* |
* 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 |
* on 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 |
* THE AUTHOR(S) AND/OR THEIR 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 "pipe/p_context.h" |
#include "util/u_index_modify.h" |
#include "util/u_inlines.h" |
/* Ubyte indices. */ |
void util_shorten_ubyte_elts_to_userptr(struct pipe_context *context, |
struct pipe_index_buffer *ib, |
int index_bias, |
unsigned start, |
unsigned count, |
void *out) |
{ |
struct pipe_transfer *src_transfer = NULL; |
const unsigned char *in_map; |
unsigned short *out_map = out; |
unsigned i; |
if (ib->user_buffer) { |
in_map = ib->user_buffer; |
} else { |
in_map = pipe_buffer_map(context, ib->buffer, |
PIPE_TRANSFER_READ | |
PIPE_TRANSFER_UNSYNCHRONIZED, |
&src_transfer); |
} |
in_map += start; |
for (i = 0; i < count; i++) { |
*out_map = (unsigned short)(*in_map + index_bias); |
in_map++; |
out_map++; |
} |
if (src_transfer) |
pipe_buffer_unmap(context, src_transfer); |
} |
void util_shorten_ubyte_elts(struct pipe_context *context, |
struct pipe_index_buffer *ib, |
struct pipe_resource **out_buf, |
int index_bias, |
unsigned start, |
unsigned count) |
{ |
struct pipe_resource* new_elts; |
unsigned short *out_map; |
struct pipe_transfer *dst_transfer; |
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, |
&dst_transfer); |
util_shorten_ubyte_elts_to_userptr(context, ib, index_bias, |
start, count, out_map); |
pipe_buffer_unmap(context, dst_transfer); |
pipe_resource_reference(out_buf, NULL); |
*out_buf = new_elts; |
} |
/* Ushort indices. */ |
void util_rebuild_ushort_elts_to_userptr(struct pipe_context *context, |
struct pipe_index_buffer *ib, |
int index_bias, |
unsigned start, unsigned count, |
void *out) |
{ |
struct pipe_transfer *in_transfer = NULL; |
const unsigned short *in_map; |
unsigned short *out_map = out; |
unsigned i; |
if (ib->user_buffer) { |
in_map = ib->user_buffer; |
} else { |
in_map = pipe_buffer_map(context, ib->buffer, |
PIPE_TRANSFER_READ | |
PIPE_TRANSFER_UNSYNCHRONIZED, |
&in_transfer); |
} |
in_map += start; |
for (i = 0; i < count; i++) { |
*out_map = (unsigned short)(*in_map + index_bias); |
in_map++; |
out_map++; |
} |
if (in_transfer) |
pipe_buffer_unmap(context, in_transfer); |
} |
void util_rebuild_ushort_elts(struct pipe_context *context, |
struct pipe_index_buffer *ib, |
struct pipe_resource **out_buf, |
int index_bias, |
unsigned start, unsigned count) |
{ |
struct pipe_transfer *out_transfer = NULL; |
struct pipe_resource *new_elts; |
unsigned short *out_map; |
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, &out_transfer); |
util_rebuild_ushort_elts_to_userptr(context, ib, index_bias, |
start, count, out_map); |
pipe_buffer_unmap(context, out_transfer); |
pipe_resource_reference(out_buf, NULL); |
*out_buf = new_elts; |
} |
/* Uint indices. */ |
void util_rebuild_uint_elts_to_userptr(struct pipe_context *context, |
struct pipe_index_buffer *ib, |
int index_bias, |
unsigned start, unsigned count, |
void *out) |
{ |
struct pipe_transfer *in_transfer = NULL; |
const unsigned int *in_map; |
unsigned int *out_map = out; |
unsigned i; |
if (ib->user_buffer) { |
in_map = ib->user_buffer; |
} else { |
in_map = pipe_buffer_map(context, ib->buffer, |
PIPE_TRANSFER_READ | |
PIPE_TRANSFER_UNSYNCHRONIZED, |
&in_transfer); |
} |
in_map += start; |
for (i = 0; i < count; i++) { |
*out_map = (unsigned int)(*in_map + index_bias); |
in_map++; |
out_map++; |
} |
if (in_transfer) |
pipe_buffer_unmap(context, in_transfer); |
} |
void util_rebuild_uint_elts(struct pipe_context *context, |
struct pipe_index_buffer *ib, |
struct pipe_resource **out_buf, |
int index_bias, |
unsigned start, unsigned count) |
{ |
struct pipe_transfer *out_transfer = NULL; |
struct pipe_resource *new_elts; |
unsigned int *out_map; |
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, &out_transfer); |
util_rebuild_uint_elts_to_userptr(context, ib, index_bias, |
start, count, out_map); |
pipe_buffer_unmap(context, out_transfer); |
pipe_resource_reference(out_buf, NULL); |
*out_buf = new_elts; |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_index_modify.h |
---|
0,0 → 1,72 |
/* |
* Copyright 2010 Marek Olšák <maraeo@gmail.com> |
* |
* 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 |
* on 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 |
* THE AUTHOR(S) AND/OR THEIR 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 UTIL_INDEX_MODIFY_H |
#define UTIL_INDEX_MODIFY_H |
struct pipe_context; |
struct pipe_resource; |
struct pipe_index_buffer; |
void util_shorten_ubyte_elts_to_userptr(struct pipe_context *context, |
struct pipe_index_buffer *ib, |
int index_bias, |
unsigned start, |
unsigned count, |
void *out); |
void util_shorten_ubyte_elts(struct pipe_context *context, |
struct pipe_index_buffer *ib, |
struct pipe_resource **out_buf, |
int index_bias, |
unsigned start, |
unsigned count); |
void util_rebuild_ushort_elts_to_userptr(struct pipe_context *context, |
struct pipe_index_buffer *ib, |
int index_bias, |
unsigned start, unsigned count, |
void *out); |
void util_rebuild_ushort_elts(struct pipe_context *context, |
struct pipe_index_buffer *ib, |
struct pipe_resource **out_buf, |
int index_bias, |
unsigned start, unsigned count); |
void util_rebuild_uint_elts_to_userptr(struct pipe_context *context, |
struct pipe_index_buffer *ib, |
int index_bias, |
unsigned start, unsigned count, |
void *out); |
void util_rebuild_uint_elts(struct pipe_context *context, |
struct pipe_index_buffer *ib, |
struct pipe_resource **out_buf, |
int index_bias, |
unsigned start, unsigned count); |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_init.h |
---|
0,0 → 1,52 |
/* |
* Copyright 2010 Luca Barbieri |
* |
* 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, sublicense, 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 NONINFRINGEMENT. |
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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_INIT_H |
#define U_INIT_H |
/* Use UTIL_INIT(f) to have f called at program initialization. |
Note that it is only guaranteed to be called if any symbol in the |
.c file it is in sis referenced by the program. |
UTIL_INIT functions are called in arbitrary order. |
*/ |
#ifdef __cplusplus |
/* use a C++ global constructor */ |
#define UTIL_INIT(f) struct f##__gctor_t {f##__gctor_t() {x();}} f##__gctor; |
#elif defined(_MSC_VER) |
/* add a pointer to the section where MSVC stores global constructor pointers */ |
/* see http://blogs.msdn.com/vcblog/archive/2006/10/20/crt-initialization.aspx and |
http://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc */ |
#pragma section(".CRT$XCU",read) |
#define UTIL_INIT(f) static void __cdecl f##__init(void) {f();}; __declspec(allocate(".CRT$XCU")) void (__cdecl* f##__xcu)(void) = f##__init; |
#elif defined(__GNUC__) |
#define UTIL_INIT(f) static void f##__init(void) __attribute__((constructor)); static void f##__init(void) {f();} |
#else |
#error Unsupported compiler: please find out how to implement global initializers in C on it |
#endif |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_inlines.h |
---|
0,0 → 1,605 |
/************************************************************************** |
* |
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. |
* 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 TUNGSTEN GRAPHICS 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_INLINES_H |
#define U_INLINES_H |
#include "pipe/p_context.h" |
#include "pipe/p_defines.h" |
#include "pipe/p_shader_tokens.h" |
#include "pipe/p_state.h" |
#include "pipe/p_screen.h" |
#include "util/u_debug.h" |
#include "util/u_debug_describe.h" |
#include "util/u_debug_refcnt.h" |
#include "util/u_atomic.h" |
#include "util/u_box.h" |
#include "util/u_math.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
/* |
* Reference counting helper functions. |
*/ |
static INLINE void |
pipe_reference_init(struct pipe_reference *reference, unsigned count) |
{ |
p_atomic_set(&reference->count, count); |
} |
static INLINE boolean |
pipe_is_referenced(struct pipe_reference *reference) |
{ |
return p_atomic_read(&reference->count) != 0; |
} |
/** |
* Update reference counting. |
* The old thing pointed to, if any, will be unreferenced. |
* Both 'ptr' and 'reference' may be NULL. |
* \return TRUE if the object's refcount hits zero and should be destroyed. |
*/ |
static INLINE boolean |
pipe_reference_described(struct pipe_reference *ptr, |
struct pipe_reference *reference, |
debug_reference_descriptor get_desc) |
{ |
boolean destroy = FALSE; |
if(ptr != reference) { |
/* bump the reference.count first */ |
if (reference) { |
assert(pipe_is_referenced(reference)); |
p_atomic_inc(&reference->count); |
debug_reference(reference, get_desc, 1); |
} |
if (ptr) { |
assert(pipe_is_referenced(ptr)); |
if (p_atomic_dec_zero(&ptr->count)) { |
destroy = TRUE; |
} |
debug_reference(ptr, get_desc, -1); |
} |
} |
return destroy; |
} |
static INLINE boolean |
pipe_reference(struct pipe_reference *ptr, struct pipe_reference *reference) |
{ |
return pipe_reference_described(ptr, reference, |
(debug_reference_descriptor)debug_describe_reference); |
} |
static INLINE void |
pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf) |
{ |
struct pipe_surface *old_surf = *ptr; |
if (pipe_reference_described(&(*ptr)->reference, &surf->reference, |
(debug_reference_descriptor)debug_describe_surface)) |
old_surf->context->surface_destroy(old_surf->context, old_surf); |
*ptr = surf; |
} |
/** |
* Similar to pipe_surface_reference() but always set the pointer to NULL |
* and pass in an explicit context. The explicit context avoids the problem |
* of using a deleted context's surface_destroy() method when freeing a surface |
* that's shared by multiple contexts. |
*/ |
static INLINE void |
pipe_surface_release(struct pipe_context *pipe, struct pipe_surface **ptr) |
{ |
if (pipe_reference_described(&(*ptr)->reference, NULL, |
(debug_reference_descriptor)debug_describe_surface)) |
pipe->surface_destroy(pipe, *ptr); |
*ptr = NULL; |
} |
static INLINE void |
pipe_resource_reference(struct pipe_resource **ptr, struct pipe_resource *tex) |
{ |
struct pipe_resource *old_tex = *ptr; |
if (pipe_reference_described(&(*ptr)->reference, &tex->reference, |
(debug_reference_descriptor)debug_describe_resource)) |
old_tex->screen->resource_destroy(old_tex->screen, old_tex); |
*ptr = tex; |
} |
static INLINE void |
pipe_sampler_view_reference(struct pipe_sampler_view **ptr, struct pipe_sampler_view *view) |
{ |
struct pipe_sampler_view *old_view = *ptr; |
if (pipe_reference_described(&(*ptr)->reference, &view->reference, |
(debug_reference_descriptor)debug_describe_sampler_view)) |
old_view->context->sampler_view_destroy(old_view->context, old_view); |
*ptr = view; |
} |
/** |
* Similar to pipe_sampler_view_reference() but always set the pointer to |
* NULL and pass in an explicit context. Passing an explicit context is a |
* work-around for fixing a dangling context pointer problem when textures |
* are shared by multiple contexts. XXX fix this someday. |
*/ |
static INLINE void |
pipe_sampler_view_release(struct pipe_context *ctx, |
struct pipe_sampler_view **ptr) |
{ |
struct pipe_sampler_view *old_view = *ptr; |
if (*ptr && (*ptr)->context != ctx) { |
debug_printf_once(("context mis-match in pipe_sampler_view_release()\n")); |
} |
if (pipe_reference_described(&(*ptr)->reference, NULL, |
(debug_reference_descriptor)debug_describe_sampler_view)) { |
ctx->sampler_view_destroy(ctx, old_view); |
} |
*ptr = NULL; |
} |
static INLINE void |
pipe_so_target_reference(struct pipe_stream_output_target **ptr, |
struct pipe_stream_output_target *target) |
{ |
struct pipe_stream_output_target *old = *ptr; |
if (pipe_reference_described(&(*ptr)->reference, &target->reference, |
(debug_reference_descriptor)debug_describe_so_target)) |
old->context->stream_output_target_destroy(old->context, old); |
*ptr = target; |
} |
static INLINE void |
pipe_surface_reset(struct pipe_context *ctx, struct pipe_surface* ps, |
struct pipe_resource *pt, unsigned level, unsigned layer) |
{ |
pipe_resource_reference(&ps->texture, pt); |
ps->format = pt->format; |
ps->width = u_minify(pt->width0, level); |
ps->height = u_minify(pt->height0, level); |
ps->u.tex.level = level; |
ps->u.tex.first_layer = ps->u.tex.last_layer = layer; |
ps->context = ctx; |
} |
static INLINE void |
pipe_surface_init(struct pipe_context *ctx, struct pipe_surface* ps, |
struct pipe_resource *pt, unsigned level, unsigned layer) |
{ |
ps->texture = 0; |
pipe_reference_init(&ps->reference, 1); |
pipe_surface_reset(ctx, ps, pt, level, layer); |
} |
/* 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. |
*/ |
static INLINE struct pipe_resource * |
pipe_buffer_create( struct pipe_screen *screen, |
unsigned bind, |
unsigned usage, |
unsigned size ) |
{ |
struct pipe_resource buffer; |
memset(&buffer, 0, sizeof buffer); |
buffer.target = PIPE_BUFFER; |
buffer.format = PIPE_FORMAT_R8_UNORM; /* want TYPELESS or similar */ |
buffer.bind = bind; |
buffer.usage = usage; |
buffer.flags = 0; |
buffer.width0 = size; |
buffer.height0 = 1; |
buffer.depth0 = 1; |
buffer.array_size = 1; |
return screen->resource_create(screen, &buffer); |
} |
static INLINE void * |
pipe_buffer_map_range(struct pipe_context *pipe, |
struct pipe_resource *buffer, |
unsigned offset, |
unsigned length, |
unsigned usage, |
struct pipe_transfer **transfer) |
{ |
struct pipe_box box; |
void *map; |
assert(offset < buffer->width0); |
assert(offset + length <= buffer->width0); |
assert(length); |
u_box_1d(offset, length, &box); |
map = pipe->transfer_map(pipe, buffer, 0, usage, &box, transfer); |
if (map == NULL) { |
return NULL; |
} |
return map; |
} |
static INLINE void * |
pipe_buffer_map(struct pipe_context *pipe, |
struct pipe_resource *buffer, |
unsigned usage, |
struct pipe_transfer **transfer) |
{ |
return pipe_buffer_map_range(pipe, buffer, 0, buffer->width0, usage, transfer); |
} |
static INLINE void |
pipe_buffer_unmap(struct pipe_context *pipe, |
struct pipe_transfer *transfer) |
{ |
pipe->transfer_unmap(pipe, transfer); |
} |
static INLINE void |
pipe_buffer_flush_mapped_range(struct pipe_context *pipe, |
struct pipe_transfer *transfer, |
unsigned offset, |
unsigned length) |
{ |
struct pipe_box box; |
int transfer_offset; |
assert(length); |
assert(transfer->box.x <= (int) offset); |
assert((int) (offset + length) <= transfer->box.x + transfer->box.width); |
/* Match old screen->buffer_flush_mapped_range() behaviour, where |
* offset parameter is relative to the start of the buffer, not the |
* mapped range. |
*/ |
transfer_offset = offset - transfer->box.x; |
u_box_1d(transfer_offset, length, &box); |
pipe->transfer_flush_region(pipe, transfer, &box); |
} |
static INLINE void |
pipe_buffer_write(struct pipe_context *pipe, |
struct pipe_resource *buf, |
unsigned offset, |
unsigned size, |
const void *data) |
{ |
struct pipe_box box; |
unsigned usage = PIPE_TRANSFER_WRITE; |
if (offset == 0 && size == buf->width0) { |
usage |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE; |
} else { |
usage |= PIPE_TRANSFER_DISCARD_RANGE; |
} |
u_box_1d(offset, size, &box); |
pipe->transfer_inline_write( pipe, |
buf, |
0, |
usage, |
&box, |
data, |
size, |
0); |
} |
/** |
* Special case for writing non-overlapping ranges. |
* |
* We can avoid GPU/CPU synchronization when writing range that has never |
* been written before. |
*/ |
static INLINE void |
pipe_buffer_write_nooverlap(struct pipe_context *pipe, |
struct pipe_resource *buf, |
unsigned offset, unsigned size, |
const void *data) |
{ |
struct pipe_box box; |
u_box_1d(offset, size, &box); |
pipe->transfer_inline_write(pipe, |
buf, |
0, |
(PIPE_TRANSFER_WRITE | |
PIPE_TRANSFER_UNSYNCHRONIZED), |
&box, |
data, |
0, 0); |
} |
static INLINE struct pipe_resource * |
pipe_buffer_create_with_data(struct pipe_context *pipe, |
unsigned bind, |
unsigned usage, |
unsigned size, |
void *ptr) |
{ |
struct pipe_resource *res = pipe_buffer_create(pipe->screen, |
bind, usage, size); |
pipe_buffer_write_nooverlap(pipe, res, 0, size, ptr); |
return res; |
} |
static INLINE void |
pipe_buffer_read(struct pipe_context *pipe, |
struct pipe_resource *buf, |
unsigned offset, |
unsigned size, |
void *data) |
{ |
struct pipe_transfer *src_transfer; |
ubyte *map; |
map = (ubyte *) pipe_buffer_map_range(pipe, |
buf, |
offset, size, |
PIPE_TRANSFER_READ, |
&src_transfer); |
if (!map) |
return; |
memcpy(data, map, size); |
pipe_buffer_unmap(pipe, src_transfer); |
} |
static INLINE void * |
pipe_transfer_map(struct pipe_context *context, |
struct pipe_resource *resource, |
unsigned level, unsigned layer, |
enum pipe_transfer_usage usage, |
unsigned x, unsigned y, |
unsigned w, unsigned h, |
struct pipe_transfer **transfer) |
{ |
struct pipe_box box; |
u_box_2d_zslice(x, y, layer, w, h, &box); |
return context->transfer_map(context, |
resource, |
level, |
usage, |
&box, transfer); |
} |
static INLINE void * |
pipe_transfer_map_3d(struct pipe_context *context, |
struct pipe_resource *resource, |
unsigned level, |
enum pipe_transfer_usage usage, |
unsigned x, unsigned y, unsigned z, |
unsigned w, unsigned h, unsigned d, |
struct pipe_transfer **transfer) |
{ |
struct pipe_box box; |
u_box_3d(x, y, z, w, h, d, &box); |
return context->transfer_map(context, |
resource, |
level, |
usage, |
&box, transfer); |
} |
static INLINE void |
pipe_transfer_unmap( struct pipe_context *context, |
struct pipe_transfer *transfer ) |
{ |
context->transfer_unmap( context, transfer ); |
} |
static INLINE void |
pipe_set_constant_buffer(struct pipe_context *pipe, uint shader, uint index, |
struct pipe_resource *buf) |
{ |
if (buf) { |
struct pipe_constant_buffer cb; |
cb.buffer = buf; |
cb.buffer_offset = 0; |
cb.buffer_size = buf->width0; |
cb.user_buffer = NULL; |
pipe->set_constant_buffer(pipe, shader, index, &cb); |
} else { |
pipe->set_constant_buffer(pipe, shader, index, NULL); |
} |
} |
static INLINE boolean util_get_offset( |
const struct pipe_rasterizer_state *templ, |
unsigned fill_mode) |
{ |
switch(fill_mode) { |
case PIPE_POLYGON_MODE_POINT: |
return templ->offset_point; |
case PIPE_POLYGON_MODE_LINE: |
return templ->offset_line; |
case PIPE_POLYGON_MODE_FILL: |
return templ->offset_tri; |
default: |
assert(0); |
return FALSE; |
} |
} |
static INLINE float |
util_get_min_point_size(const struct pipe_rasterizer_state *state) |
{ |
/* The point size should be clamped to this value at the rasterizer stage. |
*/ |
return !state->point_quad_rasterization && |
!state->point_smooth && |
!state->multisample ? 1.0f : 0.0f; |
} |
static INLINE void |
util_query_clear_result(union pipe_query_result *result, unsigned type) |
{ |
switch (type) { |
case PIPE_QUERY_OCCLUSION_PREDICATE: |
case PIPE_QUERY_SO_OVERFLOW_PREDICATE: |
case PIPE_QUERY_GPU_FINISHED: |
result->b = FALSE; |
break; |
case PIPE_QUERY_OCCLUSION_COUNTER: |
case PIPE_QUERY_TIMESTAMP: |
case PIPE_QUERY_TIME_ELAPSED: |
case PIPE_QUERY_PRIMITIVES_GENERATED: |
case PIPE_QUERY_PRIMITIVES_EMITTED: |
result->u64 = 0; |
break; |
case PIPE_QUERY_SO_STATISTICS: |
memset(&result->so_statistics, 0, sizeof(result->so_statistics)); |
break; |
case PIPE_QUERY_TIMESTAMP_DISJOINT: |
memset(&result->timestamp_disjoint, 0, sizeof(result->timestamp_disjoint)); |
break; |
case PIPE_QUERY_PIPELINE_STATISTICS: |
memset(&result->pipeline_statistics, 0, sizeof(result->pipeline_statistics)); |
break; |
default: |
memset(result, 0, sizeof(*result)); |
} |
} |
/** Convert PIPE_TEXTURE_x to TGSI_TEXTURE_x */ |
static INLINE unsigned |
util_pipe_tex_to_tgsi_tex(enum pipe_texture_target pipe_tex_target, |
unsigned nr_samples) |
{ |
switch (pipe_tex_target) { |
case PIPE_TEXTURE_1D: |
assert(nr_samples <= 1); |
return TGSI_TEXTURE_1D; |
case PIPE_TEXTURE_2D: |
return nr_samples > 1 ? TGSI_TEXTURE_2D_MSAA : TGSI_TEXTURE_2D; |
case PIPE_TEXTURE_RECT: |
assert(nr_samples <= 1); |
return TGSI_TEXTURE_RECT; |
case PIPE_TEXTURE_3D: |
assert(nr_samples <= 1); |
return TGSI_TEXTURE_3D; |
case PIPE_TEXTURE_CUBE: |
assert(nr_samples <= 1); |
return TGSI_TEXTURE_CUBE; |
case PIPE_TEXTURE_1D_ARRAY: |
assert(nr_samples <= 1); |
return TGSI_TEXTURE_1D_ARRAY; |
case PIPE_TEXTURE_2D_ARRAY: |
return nr_samples > 1 ? TGSI_TEXTURE_2D_ARRAY_MSAA : |
TGSI_TEXTURE_2D_ARRAY; |
case PIPE_TEXTURE_CUBE_ARRAY: |
return TGSI_TEXTURE_CUBE_ARRAY; |
default: |
assert(0 && "unexpected texture target"); |
return TGSI_TEXTURE_UNKNOWN; |
} |
} |
static INLINE void |
util_copy_constant_buffer(struct pipe_constant_buffer *dst, |
const struct pipe_constant_buffer *src) |
{ |
if (src) { |
pipe_resource_reference(&dst->buffer, src->buffer); |
dst->buffer_offset = src->buffer_offset; |
dst->buffer_size = src->buffer_size; |
dst->user_buffer = src->user_buffer; |
} |
else { |
pipe_resource_reference(&dst->buffer, NULL); |
dst->buffer_offset = 0; |
dst->buffer_size = 0; |
dst->user_buffer = NULL; |
} |
} |
static INLINE unsigned |
util_max_layer(const struct pipe_resource *r, unsigned level) |
{ |
switch (r->target) { |
case PIPE_TEXTURE_CUBE: |
return 6 - 1; |
case PIPE_TEXTURE_3D: |
return u_minify(r->depth0, level) - 1; |
case PIPE_TEXTURE_1D_ARRAY: |
case PIPE_TEXTURE_2D_ARRAY: |
case PIPE_TEXTURE_CUBE_ARRAY: |
return r->array_size - 1; |
default: |
return 0; |
} |
} |
#ifdef __cplusplus |
} |
#endif |
#endif /* U_INLINES_H */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_keymap.c |
---|
0,0 → 1,318 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* 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 TUNGSTEN GRAPHICS 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. |
* |
**************************************************************************/ |
/** |
* Key lookup/associative container. |
* |
* Like Jose's util_hash_table, based on CSO cache code for now. |
* |
* Author: Brian Paul |
*/ |
#include "pipe/p_compiler.h" |
#include "util/u_debug.h" |
#include "cso_cache/cso_hash.h" |
#include "util/u_memory.h" |
#include "util/u_keymap.h" |
struct keymap |
{ |
struct cso_hash *cso; |
unsigned key_size; |
unsigned max_entries; /* XXX not obeyed net */ |
unsigned num_entries; |
keymap_delete_func delete_func; |
}; |
struct keymap_item |
{ |
void *key, *value; |
}; |
/** |
* This the default key-delete function used when the client doesn't |
* provide one. |
*/ |
static void |
default_delete_func(const struct keymap *map, |
const void *key, void *data, void *user) |
{ |
FREE((void*) data); |
} |
static INLINE struct keymap_item * |
hash_table_item(struct cso_hash_iter iter) |
{ |
return (struct keymap_item *) cso_hash_iter_data(iter); |
} |
/** |
* Return 4-byte hash key for a block of bytes. |
*/ |
static unsigned |
hash(const void *key, unsigned keySize) |
{ |
unsigned i, hash; |
keySize /= 4; /* convert from bytes to uints */ |
hash = 0; |
for (i = 0; i < keySize; i++) { |
hash ^= (i + 1) * ((const unsigned *) key)[i]; |
} |
/*hash = hash ^ (hash >> 11) ^ (hash >> 22);*/ |
return hash; |
} |
/** |
* Create a new map. |
* \param keySize size of the keys in bytes |
* \param maxEntries max number of entries to allow (~0 = infinity) |
* \param deleteFunc optional callback to call when entries |
* are deleted/replaced |
*/ |
struct keymap * |
util_new_keymap(unsigned keySize, unsigned maxEntries, |
keymap_delete_func deleteFunc) |
{ |
struct keymap *map = MALLOC_STRUCT(keymap); |
if (!map) |
return NULL; |
map->cso = cso_hash_create(); |
if (!map->cso) { |
FREE(map); |
return NULL; |
} |
map->max_entries = maxEntries; |
map->num_entries = 0; |
map->key_size = keySize; |
map->delete_func = deleteFunc ? deleteFunc : default_delete_func; |
return map; |
} |
/** |
* Delete/free a keymap and all entries. The deleteFunc that was given at |
* create time will be called for each entry. |
* \param user user-provided pointer passed through to the delete callback |
*/ |
void |
util_delete_keymap(struct keymap *map, void *user) |
{ |
util_keymap_remove_all(map, user); |
cso_hash_delete(map->cso); |
FREE(map); |
} |
static INLINE struct cso_hash_iter |
hash_table_find_iter(const struct keymap *map, const void *key, |
unsigned key_hash) |
{ |
struct cso_hash_iter iter; |
struct keymap_item *item; |
iter = cso_hash_find(map->cso, key_hash); |
while (!cso_hash_iter_is_null(iter)) { |
item = (struct keymap_item *) cso_hash_iter_data(iter); |
if (!memcmp(item->key, key, map->key_size)) |
break; |
iter = cso_hash_iter_next(iter); |
} |
return iter; |
} |
static INLINE struct keymap_item * |
hash_table_find_item(const struct keymap *map, const void *key, |
unsigned key_hash) |
{ |
struct cso_hash_iter iter = hash_table_find_iter(map, key, key_hash); |
if (cso_hash_iter_is_null(iter)) { |
return NULL; |
} |
else { |
return hash_table_item(iter); |
} |
} |
/** |
* Insert a new key + data pointer into the table. |
* Note: we create a copy of the key, but not the data! |
* If the key is already present in the table, replace the existing |
* entry (calling the delete callback on the previous entry). |
* If the maximum capacity of the map is reached an old entry |
* will be deleted (the delete callback will be called). |
*/ |
boolean |
util_keymap_insert(struct keymap *map, const void *key, |
const void *data, void *user) |
{ |
unsigned key_hash; |
struct keymap_item *item; |
struct cso_hash_iter iter; |
assert(map); |
if (!map) |
return FALSE; |
key_hash = hash(key, map->key_size); |
item = hash_table_find_item(map, key, key_hash); |
if (item) { |
/* call delete callback for old entry/item */ |
map->delete_func(map, item->key, item->value, user); |
item->value = (void *) data; |
return TRUE; |
} |
item = MALLOC_STRUCT(keymap_item); |
if (!item) |
return FALSE; |
item->key = mem_dup(key, map->key_size); |
item->value = (void *) data; |
iter = cso_hash_insert(map->cso, key_hash, item); |
if (cso_hash_iter_is_null(iter)) { |
FREE(item); |
return FALSE; |
} |
map->num_entries++; |
return TRUE; |
} |
/** |
* Look up a key in the map and return the associated data pointer. |
*/ |
const void * |
util_keymap_lookup(const struct keymap *map, const void *key) |
{ |
unsigned key_hash; |
struct keymap_item *item; |
assert(map); |
if (!map) |
return NULL; |
key_hash = hash(key, map->key_size); |
item = hash_table_find_item(map, key, key_hash); |
if (!item) |
return NULL; |
return item->value; |
} |
/** |
* Remove an entry from the map. |
* The delete callback will be called if the given key/entry is found. |
* \param user passed to the delete callback as the last param. |
*/ |
void |
util_keymap_remove(struct keymap *map, const void *key, void *user) |
{ |
unsigned key_hash; |
struct cso_hash_iter iter; |
struct keymap_item *item; |
assert(map); |
if (!map) |
return; |
key_hash = hash(key, map->key_size); |
iter = hash_table_find_iter(map, key, key_hash); |
if (cso_hash_iter_is_null(iter)) |
return; |
item = hash_table_item(iter); |
assert(item); |
if (!item) |
return; |
map->delete_func(map, item->key, item->value, user); |
FREE(item->key); |
FREE(item); |
map->num_entries--; |
cso_hash_erase(map->cso, iter); |
} |
/** |
* Remove all entries from the map, calling the delete callback for each. |
* \param user passed to the delete callback as the last param. |
*/ |
void |
util_keymap_remove_all(struct keymap *map, void *user) |
{ |
struct cso_hash_iter iter; |
struct keymap_item *item; |
assert(map); |
if (!map) |
return; |
iter = cso_hash_first_node(map->cso); |
while (!cso_hash_iter_is_null(iter)) { |
item = (struct keymap_item *) |
cso_hash_take(map->cso, cso_hash_iter_key(iter)); |
map->delete_func(map, item->key, item->value, user); |
FREE(item->key); |
FREE(item); |
iter = cso_hash_first_node(map->cso); |
} |
} |
extern void |
util_keymap_info(const struct keymap *map) |
{ |
debug_printf("Keymap %p: %u of max %u entries\n", |
(void *) map, map->num_entries, map->max_entries); |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_keymap.h |
---|
0,0 → 1,68 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* 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 TUNGSTEN GRAPHICS 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_KEYMAP_H |
#define U_KEYMAP_H |
#include "pipe/p_compiler.h" |
/** opaque keymap type */ |
struct keymap; |
/** Delete/callback function type */ |
typedef void (*keymap_delete_func)(const struct keymap *map, |
const void *key, void *data, |
void *user); |
extern struct keymap * |
util_new_keymap(unsigned keySize, unsigned maxEntries, |
keymap_delete_func deleteFunc); |
extern void |
util_delete_keymap(struct keymap *map, void *user); |
extern boolean |
util_keymap_insert(struct keymap *map, const void *key, |
const void *data, void *user); |
extern const void * |
util_keymap_lookup(const struct keymap *map, const void *key); |
extern void |
util_keymap_remove(struct keymap *map, const void *key, void *user); |
extern void |
util_keymap_remove_all(struct keymap *map, void *user); |
extern void |
util_keymap_info(const struct keymap *map); |
#endif /* U_KEYMAP_H */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_linear.c |
---|
0,0 → 1,101 |
/************************************************************************** |
* |
* Copyright 2009 VMware, Inc. |
* 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 VMWARE 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. |
* |
**************************************************************************/ |
/** |
* Functions for converting tiled data to linear and vice versa. |
*/ |
#include "util/u_debug.h" |
#include "u_linear.h" |
void |
pipe_linear_to_tile(size_t src_stride, const void *src_ptr, |
struct pipe_tile_info *t, void *dst_ptr) |
{ |
int x, y, z; |
char *ptr; |
size_t bytes = t->cols * t->block.size; |
char *dst_ptr2 = (char *) dst_ptr; |
assert(pipe_linear_check_tile(t)); |
/* lets write lineary to the tiled buffer */ |
for (y = 0; y < t->tiles_y; y++) { |
for (x = 0; x < t->tiles_x; x++) { |
/* this inner loop could be replace with SSE magic */ |
ptr = (char*)src_ptr + src_stride * t->rows * y + bytes * x; |
for (z = 0; z < t->rows; z++) { |
memcpy(dst_ptr2, ptr, bytes); |
dst_ptr2 += bytes; |
ptr += src_stride; |
} |
} |
} |
} |
void pipe_linear_from_tile(struct pipe_tile_info *t, const void *src_ptr, |
size_t dst_stride, void *dst_ptr) |
{ |
int x, y, z; |
char *ptr; |
size_t bytes = t->cols * t->block.size; |
const char *src_ptr2 = (const char *) src_ptr; |
/* lets read lineary from the tiled buffer */ |
for (y = 0; y < t->tiles_y; y++) { |
for (x = 0; x < t->tiles_x; x++) { |
/* this inner loop could be replace with SSE magic */ |
ptr = (char*)dst_ptr + dst_stride * t->rows * y + bytes * x; |
for (z = 0; z < t->rows; z++) { |
memcpy(ptr, src_ptr2, bytes); |
src_ptr2 += bytes; |
ptr += dst_stride; |
} |
} |
} |
} |
void |
pipe_linear_fill_info(struct pipe_tile_info *t, |
const struct u_linear_format_block *block, |
unsigned tile_width, unsigned tile_height, |
unsigned tiles_x, unsigned tiles_y) |
{ |
t->block = *block; |
t->tile.width = tile_width; |
t->tile.height = tile_height; |
t->cols = t->tile.width / t->block.width; |
t->rows = t->tile.height / t->block.height; |
t->tile.size = t->cols * t->rows * t->block.size; |
t->tiles_x = tiles_x; |
t->tiles_y = tiles_y; |
t->stride = t->cols * t->tiles_x * t->block.size; |
t->size = t->tiles_x * t->tiles_y * t->tile.size; |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_linear.h |
---|
0,0 → 1,106 |
/************************************************************************** |
* |
* Copyright 2009 VMware, Inc. |
* 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 VMWARE 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. |
* |
**************************************************************************/ |
/** |
* Functions for converting tiled data to linear and vice versa. |
*/ |
#ifndef U_LINEAR_H |
#define U_LINEAR_H |
#include "pipe/p_compiler.h" |
#include "pipe/p_format.h" |
struct u_linear_format_block |
{ |
/** Block size in bytes */ |
unsigned size; |
/** Block width in pixels */ |
unsigned width; |
/** Block height in pixels */ |
unsigned height; |
}; |
struct pipe_tile_info |
{ |
unsigned size; |
unsigned stride; |
/* The number of tiles */ |
unsigned tiles_x; |
unsigned tiles_y; |
/* size of each tile expressed in blocks */ |
unsigned cols; |
unsigned rows; |
/* Describe the tile in pixels */ |
struct u_linear_format_block tile; |
/* Describe each block within the tile */ |
struct u_linear_format_block block; |
}; |
void pipe_linear_to_tile(size_t src_stride, const void *src_ptr, |
struct pipe_tile_info *t, void *dst_ptr); |
void pipe_linear_from_tile(struct pipe_tile_info *t, const void *src_ptr, |
size_t dst_stride, void *dst_ptr); |
/** |
* Convenience function to fillout a pipe_tile_info struct. |
* @t info to fill out. |
* @block block info about pixel layout |
* @tile_width the width of the tile in pixels |
* @tile_height the height of the tile in pixels |
* @tiles_x number of tiles in x axis |
* @tiles_y number of tiles in y axis |
*/ |
void pipe_linear_fill_info(struct pipe_tile_info *t, |
const struct u_linear_format_block *block, |
unsigned tile_width, unsigned tile_height, |
unsigned tiles_x, unsigned tiles_y); |
static INLINE boolean pipe_linear_check_tile(const struct pipe_tile_info *t) |
{ |
if (t->tile.size != t->block.size * t->cols * t->rows) |
return FALSE; |
if (t->stride != t->block.size * t->cols * t->tiles_x) |
return FALSE; |
if (t->size < t->stride * t->rows * t->tiles_y) |
return FALSE; |
return TRUE; |
} |
#endif /* U_LINEAR_H */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_linkage.c |
---|
0,0 → 1,149 |
/************************************************************************** |
* |
* Copyright 2010 Luca Barbieri |
* |
* 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, sublicense, 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 NONINFRINGEMENT. |
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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_debug.h" |
#include "pipe/p_shader_tokens.h" |
#include "tgsi/tgsi_parse.h" |
#include "tgsi/tgsi_scan.h" |
#include "util/u_linkage.h" |
/* we must only record the registers that are actually used, not just declared */ |
static INLINE boolean |
util_semantic_set_test_and_set(struct util_semantic_set *set, unsigned value) |
{ |
unsigned mask = 1 << (value % (sizeof(long) * 8)); |
unsigned long *p = &set->masks[value / (sizeof(long) * 8)]; |
unsigned long v = *p & mask; |
*p |= mask; |
return !!v; |
} |
unsigned |
util_semantic_set_from_program_file(struct util_semantic_set *set, const struct tgsi_token *tokens, enum tgsi_file_type file) |
{ |
struct tgsi_shader_info info; |
struct tgsi_parse_context parse; |
unsigned count = 0; |
ubyte *semantic_name; |
ubyte *semantic_index; |
tgsi_scan_shader(tokens, &info); |
if(file == TGSI_FILE_INPUT) |
{ |
semantic_name = info.input_semantic_name; |
semantic_index = info.input_semantic_index; |
} |
else if(file == TGSI_FILE_OUTPUT) |
{ |
semantic_name = info.output_semantic_name; |
semantic_index = info.output_semantic_index; |
} |
else |
{ |
assert(0); |
semantic_name = NULL; |
semantic_index = NULL; |
} |
tgsi_parse_init(&parse, tokens); |
memset(set->masks, 0, sizeof(set->masks)); |
while(!tgsi_parse_end_of_tokens(&parse)) |
{ |
tgsi_parse_token(&parse); |
if(parse.FullToken.Token.Type == TGSI_TOKEN_TYPE_INSTRUCTION) |
{ |
const struct tgsi_full_instruction *finst = &parse.FullToken.FullInstruction; |
unsigned i; |
for(i = 0; i < finst->Instruction.NumDstRegs; ++i) |
{ |
if(finst->Dst[i].Register.File == file) |
{ |
unsigned idx = finst->Dst[i].Register.Index; |
if(semantic_name[idx] == TGSI_SEMANTIC_GENERIC) |
{ |
if(!util_semantic_set_test_and_set(set, semantic_index[idx])) |
++count; |
} |
} |
} |
for(i = 0; i < finst->Instruction.NumSrcRegs; ++i) |
{ |
if(finst->Src[i].Register.File == file) |
{ |
unsigned idx = finst->Src[i].Register.Index; |
if(semantic_name[idx] == TGSI_SEMANTIC_GENERIC) |
{ |
if(!util_semantic_set_test_and_set(set, semantic_index[idx])) |
++count; |
} |
} |
} |
} |
} |
tgsi_parse_free(&parse); |
return count; |
} |
#define UTIL_SEMANTIC_SET_FOR_EACH(i, set) for(i = 0; i < 256; ++i) if(set->masks[i / (sizeof(long) * 8)] & (1 << (i % (sizeof(long) * 8)))) |
void |
util_semantic_layout_from_set(unsigned char *layout, const struct util_semantic_set *set, unsigned efficient_slots, unsigned num_slots) |
{ |
int first = -1; |
int last = -1; |
unsigned i; |
memset(layout, 0xff, num_slots); |
UTIL_SEMANTIC_SET_FOR_EACH(i, set) |
{ |
if(first < 0) |
first = i; |
last = i; |
} |
if (last < (int) efficient_slots) |
{ |
UTIL_SEMANTIC_SET_FOR_EACH(i, set) |
layout[i] = i; |
} |
else if ((last - first) < (int) efficient_slots) |
{ |
UTIL_SEMANTIC_SET_FOR_EACH(i, set) |
layout[i - first] = i; |
} |
else |
{ |
unsigned idx = 0; |
UTIL_SEMANTIC_SET_FOR_EACH(i, set) |
layout[idx++] = i; |
} |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_linkage.h |
---|
0,0 → 1,67 |
/************************************************************************** |
* |
* Copyright 2010 Luca Barbieri |
* |
* 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, sublicense, 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 NONINFRINGEMENT. |
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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_LINKAGE_H_ |
#define U_LINKAGE_H_ |
#include "pipe/p_compiler.h" |
#include "pipe/p_shader_tokens.h" |
struct util_semantic_set |
{ |
unsigned long masks[256 / 8 / sizeof(unsigned long)]; |
}; |
static INLINE boolean |
util_semantic_set_contains(struct util_semantic_set *set, unsigned char value) |
{ |
return !!(set->masks[value / (sizeof(long) * 8)] & (1 << (value / (sizeof(long) * 8)))); |
} |
unsigned util_semantic_set_from_program_file(struct util_semantic_set *set, const struct tgsi_token *tokens, enum tgsi_file_type file); |
/* efficient_slots is the number of slots such that hardware performance is |
* the same for using that amount, with holes, or less slots but with less |
* holes. |
* |
* num_slots is the size of the layout array and hardware limit instead. |
* |
* efficient_slots == 0 or efficient_slots == num_slots are typical settings. |
*/ |
void util_semantic_layout_from_set(unsigned char *layout, const struct util_semantic_set *set, unsigned efficient_slots, unsigned num_slots); |
static INLINE void |
util_semantic_table_from_layout(unsigned char *table, size_t table_size, unsigned char *layout, |
unsigned char first_slot_value, unsigned char num_slots) |
{ |
unsigned char i; |
memset(table, 0xff, table_size); |
for(i = 0; i < num_slots; ++i) |
table[layout[i]] = first_slot_value + i; |
} |
#endif /* U_LINKAGE_H_ */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_math.c |
---|
0,0 → 1,137 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* 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 TUNGSTEN GRAPHICS 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 "pipe/p_config.h" |
#include "util/u_math.h" |
#include "util/u_cpu_detect.h" |
#if defined(PIPE_ARCH_SSE) |
#include <xmmintrin.h> |
/* This is defined in pmmintrin.h, but it can only be included when -msse3 is |
* used, so just define it here to avoid further. */ |
#define _MM_DENORMALS_ZERO_MASK 0x0040 |
#endif |
/** 2^x, for x in [-1.0, 1.0) */ |
float pow2_table[POW2_TABLE_SIZE]; |
static void |
init_pow2_table(void) |
{ |
int i; |
for (i = 0; i < POW2_TABLE_SIZE; i++) |
pow2_table[i] = (float) pow(2.0, (i - POW2_TABLE_OFFSET) / POW2_TABLE_SCALE); |
} |
/** log2(x), for x in [1.0, 2.0) */ |
float log2_table[LOG2_TABLE_SIZE]; |
static void |
init_log2_table(void) |
{ |
unsigned i; |
for (i = 0; i < LOG2_TABLE_SIZE; i++) |
log2_table[i] = (float) log2(1.0 + i * (1.0 / LOG2_TABLE_SCALE)); |
} |
/** |
* One time init for math utilities. |
*/ |
void |
util_init_math(void) |
{ |
static boolean initialized = FALSE; |
if (!initialized) { |
init_pow2_table(); |
init_log2_table(); |
initialized = TRUE; |
} |
} |
/** |
* Fetches the contents of the fpstate (mxcsr on x86) register. |
* |
* On platforms without support for it just returns 0. |
*/ |
unsigned |
util_fpstate_get(void) |
{ |
unsigned mxcsr = 0; |
#if defined(PIPE_ARCH_SSE) |
if (util_cpu_caps.has_sse) { |
mxcsr = _mm_getcsr(); |
} |
#endif |
return mxcsr; |
} |
/** |
* Make sure that the fp treats the denormalized floating |
* point numbers as zero. |
* |
* This is the behavior required by D3D10. OpenGL doesn't care. |
*/ |
unsigned |
util_fpstate_set_denorms_to_zero(unsigned current_mxcsr) |
{ |
#if defined(PIPE_ARCH_SSE) |
if (util_cpu_caps.has_sse) { |
/* Enable flush to zero mode */ |
current_mxcsr |= _MM_FLUSH_ZERO_MASK; |
if (util_cpu_caps.has_sse3) { |
/* Enable denormals are zero mode */ |
current_mxcsr |= _MM_DENORMALS_ZERO_MASK; |
} |
util_fpstate_set(current_mxcsr); |
} |
#endif |
return current_mxcsr; |
} |
/** |
* Set the state of the fpstate (mxcsr on x86) register. |
* |
* On platforms without support for it's a noop. |
*/ |
void |
util_fpstate_set(unsigned mxcsr) |
{ |
#if defined(PIPE_ARCH_SSE) |
if (util_cpu_caps.has_sse) { |
_mm_setcsr(mxcsr); |
} |
#endif |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_math.h |
---|
0,0 → 1,779 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* 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 TUNGSTEN GRAPHICS 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. |
* |
**************************************************************************/ |
/** |
* Math utilities and approximations for common math functions. |
* Reduced precision is usually acceptable in shaders... |
* |
* "fast" is used in the names of functions which are low-precision, |
* or at least lower-precision than the normal C lib functions. |
*/ |
#ifndef U_MATH_H |
#define U_MATH_H |
#include "pipe/p_compiler.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
#include <math.h> |
#include <stdarg.h> |
#ifdef PIPE_OS_UNIX |
#include <strings.h> /* for ffs */ |
#endif |
#ifndef M_SQRT2 |
#define M_SQRT2 1.41421356237309504880 |
#endif |
#if defined(_MSC_VER) |
#if _MSC_VER < 1400 && !defined(__cplusplus) |
static INLINE float cosf( float f ) |
{ |
return (float) cos( (double) f ); |
} |
static INLINE float sinf( float f ) |
{ |
return (float) sin( (double) f ); |
} |
static INLINE float ceilf( float f ) |
{ |
return (float) ceil( (double) f ); |
} |
static INLINE float floorf( float f ) |
{ |
return (float) floor( (double) f ); |
} |
static INLINE float powf( float f, float g ) |
{ |
return (float) pow( (double) f, (double) g ); |
} |
static INLINE float sqrtf( float f ) |
{ |
return (float) sqrt( (double) f ); |
} |
static INLINE float fabsf( float f ) |
{ |
return (float) fabs( (double) f ); |
} |
static INLINE float logf( float f ) |
{ |
return (float) log( (double) f ); |
} |
#else |
/* Work-around an extra semi-colon in VS 2005 logf definition */ |
#ifdef logf |
#undef logf |
#define logf(x) ((float)log((double)(x))) |
#endif /* logf */ |
#define isfinite(x) _finite((double)(x)) |
#define isnan(x) _isnan((double)(x)) |
#endif /* _MSC_VER < 1400 && !defined(__cplusplus) */ |
static INLINE double log2( double x ) |
{ |
const double invln2 = 1.442695041; |
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 */ |
#ifdef PIPE_OS_ANDROID |
static INLINE |
double log2(double d) |
{ |
return log(d) * (1.0 / M_LN2); |
} |
/* workaround a conflict with main/imports.h */ |
#ifdef log2f |
#undef log2f |
#endif |
static INLINE |
float log2f(float f) |
{ |
return logf(f) * (float) (1.0 / M_LN2); |
} |
#endif |
#define POW2_TABLE_SIZE_LOG2 9 |
#define POW2_TABLE_SIZE (1 << POW2_TABLE_SIZE_LOG2) |
#define POW2_TABLE_OFFSET (POW2_TABLE_SIZE/2) |
#define POW2_TABLE_SCALE ((float)(POW2_TABLE_SIZE/2)) |
extern float pow2_table[POW2_TABLE_SIZE]; |
/** |
* Initialize math module. This should be called before using any |
* other functions in this module. |
*/ |
extern void |
util_init_math(void); |
union fi { |
float f; |
int32_t i; |
uint32_t ui; |
}; |
union di { |
double d; |
int64_t i; |
uint64_t ui; |
}; |
/** |
* Fast version of 2^x |
* Identity: exp2(a + b) = exp2(a) * exp2(b) |
* Let ipart = int(x) |
* Let fpart = x - ipart; |
* So, exp2(x) = exp2(ipart) * exp2(fpart) |
* Compute exp2(ipart) with i << ipart |
* Compute exp2(fpart) with lookup table. |
*/ |
static INLINE float |
util_fast_exp2(float x) |
{ |
int32_t ipart; |
float fpart, mpart; |
union fi epart; |
if(x > 129.00000f) |
return 3.402823466e+38f; |
if (x < -126.99999f) |
return 0.0f; |
ipart = (int32_t) x; |
fpart = x - (float) ipart; |
/* same as |
* epart.f = (float) (1 << ipart) |
* but faster and without integer overflow for ipart > 31 |
*/ |
epart.i = (ipart + 127 ) << 23; |
mpart = pow2_table[POW2_TABLE_OFFSET + (int)(fpart * POW2_TABLE_SCALE)]; |
return epart.f * mpart; |
} |
/** |
* Fast approximation to exp(x). |
*/ |
static INLINE float |
util_fast_exp(float x) |
{ |
const float k = 1.44269f; /* = log2(e) */ |
return util_fast_exp2(k * x); |
} |
#define LOG2_TABLE_SIZE_LOG2 16 |
#define LOG2_TABLE_SCALE (1 << LOG2_TABLE_SIZE_LOG2) |
#define LOG2_TABLE_SIZE (LOG2_TABLE_SCALE + 1) |
extern float log2_table[LOG2_TABLE_SIZE]; |
/** |
* Fast approximation to log2(x). |
*/ |
static INLINE float |
util_fast_log2(float x) |
{ |
union fi num; |
float epart, mpart; |
num.f = x; |
epart = (float)(((num.i & 0x7f800000) >> 23) - 127); |
/* mpart = log2_table[mantissa*LOG2_TABLE_SCALE + 0.5] */ |
mpart = log2_table[((num.i & 0x007fffff) + (1 << (22 - LOG2_TABLE_SIZE_LOG2))) >> (23 - LOG2_TABLE_SIZE_LOG2)]; |
return epart + mpart; |
} |
/** |
* Fast approximation to x^y. |
*/ |
static INLINE float |
util_fast_pow(float x, float y) |
{ |
return util_fast_exp2(util_fast_log2(x) * y); |
} |
/* Note that this counts zero as a power of two. |
*/ |
static INLINE boolean |
util_is_power_of_two( unsigned v ) |
{ |
return (v & (v-1)) == 0; |
} |
/** |
* Floor(x), returned as int. |
*/ |
static INLINE int |
util_ifloor(float f) |
{ |
int ai, bi; |
double af, bf; |
union fi u; |
af = (3 << 22) + 0.5 + (double) f; |
bf = (3 << 22) + 0.5 - (double) f; |
u.f = (float) af; ai = u.i; |
u.f = (float) bf; bi = u.i; |
return (ai - bi) >> 1; |
} |
/** |
* Round float to nearest int. |
*/ |
static INLINE int |
util_iround(float f) |
{ |
#if defined(PIPE_CC_GCC) && defined(PIPE_ARCH_X86) |
int r; |
__asm__ ("fistpl %0" : "=m" (r) : "t" (f) : "st"); |
return r; |
#elif defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86) |
int r; |
_asm { |
fld f |
fistp r |
} |
return r; |
#else |
if (f >= 0.0f) |
return (int) (f + 0.5f); |
else |
return (int) (f - 0.5f); |
#endif |
} |
/** |
* Approximate floating point comparison |
*/ |
static INLINE boolean |
util_is_approx(float a, float b, float tol) |
{ |
return fabs(b - a) <= tol; |
} |
/** |
* util_is_X_inf_or_nan = test if x is NaN or +/- Inf |
* util_is_X_nan = test if x is NaN |
* util_X_inf_sign = return +1 for +Inf, -1 for -Inf, or 0 for not Inf |
* |
* NaN can be checked with x != x, however this fails with the fast math flag |
**/ |
/** |
* Single-float |
*/ |
static INLINE boolean |
util_is_inf_or_nan(float x) |
{ |
union fi tmp; |
tmp.f = x; |
return (tmp.ui & 0x7f800000) == 0x7f800000; |
} |
static INLINE boolean |
util_is_nan(float x) |
{ |
union fi tmp; |
tmp.f = x; |
return (tmp.ui & 0x7fffffff) > 0x7f800000; |
} |
static INLINE int |
util_inf_sign(float x) |
{ |
union fi tmp; |
tmp.f = x; |
if ((tmp.ui & 0x7fffffff) != 0x7f800000) { |
return 0; |
} |
return (x < 0) ? -1 : 1; |
} |
/** |
* Double-float |
*/ |
static INLINE boolean |
util_is_double_inf_or_nan(double x) |
{ |
union di tmp; |
tmp.d = x; |
return (tmp.ui & 0x7ff0000000000000ULL) == 0x7ff0000000000000ULL; |
} |
static INLINE boolean |
util_is_double_nan(double x) |
{ |
union di tmp; |
tmp.d = x; |
return (tmp.ui & 0x7fffffffffffffffULL) > 0x7ff0000000000000ULL; |
} |
static INLINE int |
util_double_inf_sign(double x) |
{ |
union di tmp; |
tmp.d = x; |
if ((tmp.ui & 0x7fffffffffffffffULL) != 0x7ff0000000000000ULL) { |
return 0; |
} |
return (x < 0) ? -1 : 1; |
} |
/** |
* Half-float |
*/ |
static INLINE boolean |
util_is_half_inf_or_nan(int16_t x) |
{ |
return (x & 0x7c00) == 0x7c00; |
} |
static INLINE boolean |
util_is_half_nan(int16_t x) |
{ |
return (x & 0x7fff) > 0x7c00; |
} |
static INLINE int |
util_half_inf_sign(int16_t x) |
{ |
if ((x & 0x7fff) != 0x7c00) { |
return 0; |
} |
return (x < 0) ? -1 : 1; |
} |
/** |
* Find first bit set in word. Least significant bit is 1. |
* Return 0 if no bits set. |
*/ |
#ifndef FFS_DEFINED |
#define FFS_DEFINED 1 |
#if defined(_MSC_VER) && _MSC_VER >= 1300 && (_M_IX86 || _M_AMD64 || _M_IA64) |
unsigned char _BitScanForward(unsigned long* Index, unsigned long Mask); |
#pragma intrinsic(_BitScanForward) |
static INLINE |
unsigned long ffs( unsigned long u ) |
{ |
unsigned long i; |
if (_BitScanForward(&i, u)) |
return i + 1; |
else |
return 0; |
} |
#elif defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86) |
static INLINE |
unsigned ffs( unsigned u ) |
{ |
unsigned i; |
if (u == 0) { |
return 0; |
} |
__asm bsf eax, [u] |
__asm inc eax |
__asm mov [i], eax |
return i; |
} |
#elif defined(__MINGW32__) || defined(PIPE_OS_ANDROID) |
#define ffs __builtin_ffs |
#endif |
#endif /* FFS_DEFINED */ |
/** |
* Find last bit set in a word. The least significant bit is 1. |
* Return 0 if no bits are set. |
*/ |
static INLINE unsigned util_last_bit(unsigned u) |
{ |
#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 304) |
return u == 0 ? 0 : 32 - __builtin_clz(u); |
#else |
unsigned r = 0; |
while (u) { |
r++; |
u >>= 1; |
} |
return r; |
#endif |
} |
/* Destructively loop over all of the bits in a mask as in: |
* |
* while (mymask) { |
* int i = u_bit_scan(&mymask); |
* ... process element i |
* } |
* |
*/ |
static INLINE int u_bit_scan(unsigned *mask) |
{ |
int i = ffs(*mask) - 1; |
*mask &= ~(1 << i); |
return i; |
} |
/** |
* Return float bits. |
*/ |
static INLINE unsigned |
fui( float f ) |
{ |
union fi fi; |
fi.f = f; |
return fi.ui; |
} |
/** |
* Convert ubyte to float in [0, 1]. |
* XXX a 256-entry lookup table would be slightly faster. |
*/ |
static INLINE float |
ubyte_to_float(ubyte ub) |
{ |
return (float) ub * (1.0f / 255.0f); |
} |
/** |
* Convert float in [0,1] to ubyte in [0,255] with clamping. |
*/ |
static INLINE ubyte |
float_to_ubyte(float f) |
{ |
union fi tmp; |
tmp.f = f; |
if (tmp.i < 0) { |
return (ubyte) 0; |
} |
else if (tmp.i >= 0x3f800000 /* 1.0f */) { |
return (ubyte) 255; |
} |
else { |
tmp.f = tmp.f * (255.0f/256.0f) + 32768.0f; |
return (ubyte) tmp.i; |
} |
} |
static INLINE float |
byte_to_float_tex(int8_t b) |
{ |
return (b == -128) ? -1.0F : b * 1.0F / 127.0F; |
} |
static INLINE int8_t |
float_to_byte_tex(float f) |
{ |
return (int8_t) (127.0F * f); |
} |
/** |
* Calc log base 2 |
*/ |
static INLINE unsigned |
util_logbase2(unsigned n) |
{ |
#if defined(PIPE_CC_GCC) && (PIPE_CC_GCC_VERSION >= 304) |
return ((sizeof(unsigned) * 8 - 1) - __builtin_clz(n | 1)); |
#else |
unsigned pos = 0; |
if (n >= 1<<16) { n >>= 16; pos += 16; } |
if (n >= 1<< 8) { n >>= 8; pos += 8; } |
if (n >= 1<< 4) { n >>= 4; pos += 4; } |
if (n >= 1<< 2) { n >>= 2; pos += 2; } |
if (n >= 1<< 1) { pos += 1; } |
return pos; |
#endif |
} |
/** |
* Returns the smallest power of two >= x |
*/ |
static INLINE unsigned |
util_next_power_of_two(unsigned x) |
{ |
#if defined(PIPE_CC_GCC) && (PIPE_CC_GCC_VERSION >= 304) |
if (x <= 1) |
return 1; |
return (1 << ((sizeof(unsigned) * 8) - __builtin_clz(x - 1))); |
#else |
unsigned val = x; |
if (x <= 1) |
return 1; |
if (util_is_power_of_two(x)) |
return x; |
val--; |
val = (val >> 1) | val; |
val = (val >> 2) | val; |
val = (val >> 4) | val; |
val = (val >> 8) | val; |
val = (val >> 16) | val; |
val++; |
return val; |
#endif |
} |
/** |
* Return number of bits set in n. |
*/ |
static INLINE unsigned |
util_bitcount(unsigned n) |
{ |
#if defined(PIPE_CC_GCC) && (PIPE_CC_GCC_VERSION >= 304) |
return __builtin_popcount(n); |
#else |
/* K&R classic bitcount. |
* |
* For each iteration, clear the LSB from the bitfield. |
* Requires only one iteration per set bit, instead of |
* one iteration per bit less than highest set bit. |
*/ |
unsigned bits = 0; |
for (bits; n; bits++) { |
n &= n - 1; |
} |
return bits; |
#endif |
} |
/** |
* Convert from little endian to CPU byte order. |
*/ |
#ifdef PIPE_ARCH_BIG_ENDIAN |
#define util_le32_to_cpu(x) util_bswap32(x) |
#define util_le16_to_cpu(x) util_bswap16(x) |
#else |
#define util_le32_to_cpu(x) (x) |
#define util_le16_to_cpu(x) (x) |
#endif |
/** |
* Reverse byte order of a 32 bit word. |
*/ |
static INLINE uint32_t |
util_bswap32(uint32_t n) |
{ |
#if defined(PIPE_CC_GCC) && (PIPE_CC_GCC_VERSION >= 403) |
return __builtin_bswap32(n); |
#else |
return (n >> 24) | |
((n >> 8) & 0x0000ff00) | |
((n << 8) & 0x00ff0000) | |
(n << 24); |
#endif |
} |
/** |
* Reverse byte order of a 16 bit word. |
*/ |
static INLINE uint16_t |
util_bswap16(uint16_t n) |
{ |
return (n >> 8) | |
(n << 8); |
} |
/** |
* Clamp X to [MIN, MAX]. |
* This is a macro to allow float, int, uint, etc. types. |
*/ |
#define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) ) |
#define MIN2( A, B ) ( (A)<(B) ? (A) : (B) ) |
#define MAX2( A, B ) ( (A)>(B) ? (A) : (B) ) |
#define MIN3( A, B, C ) ((A) < (B) ? MIN2(A, C) : MIN2(B, C)) |
#define MAX3( A, B, C ) ((A) > (B) ? MAX2(A, C) : MAX2(B, C)) |
#define MIN4( A, B, C, D ) ((A) < (B) ? MIN3(A, C, D) : MIN3(B, C, D)) |
#define MAX4( A, B, C, D ) ((A) > (B) ? MAX3(A, C, D) : MAX3(B, C, D)) |
/** |
* Align a value, only works pot alignemnts. |
*/ |
static INLINE int |
align(int value, int alignment) |
{ |
return (value + alignment - 1) & ~(alignment - 1); |
} |
/** |
* Works like align but on npot alignments. |
*/ |
static INLINE size_t |
util_align_npot(size_t value, size_t alignment) |
{ |
if (value % alignment) |
return value + (alignment - (value % alignment)); |
return value; |
} |
static INLINE unsigned |
u_minify(unsigned value, unsigned levels) |
{ |
return MAX2(1, value >> levels); |
} |
#ifndef COPY_4V |
#define COPY_4V( DST, SRC ) \ |
do { \ |
(DST)[0] = (SRC)[0]; \ |
(DST)[1] = (SRC)[1]; \ |
(DST)[2] = (SRC)[2]; \ |
(DST)[3] = (SRC)[3]; \ |
} while (0) |
#endif |
#ifndef COPY_4FV |
#define COPY_4FV( DST, SRC ) COPY_4V(DST, SRC) |
#endif |
#ifndef ASSIGN_4V |
#define ASSIGN_4V( DST, V0, V1, V2, V3 ) \ |
do { \ |
(DST)[0] = (V0); \ |
(DST)[1] = (V1); \ |
(DST)[2] = (V2); \ |
(DST)[3] = (V3); \ |
} while (0) |
#endif |
static INLINE uint32_t util_unsigned_fixed(float value, unsigned frac_bits) |
{ |
return value < 0 ? 0 : (uint32_t)(value * (1<<frac_bits)); |
} |
static INLINE int32_t util_signed_fixed(float value, unsigned frac_bits) |
{ |
return (int32_t)(value * (1<<frac_bits)); |
} |
unsigned |
util_fpstate_get(void); |
unsigned |
util_fpstate_set_denorms_to_zero(unsigned current_fpstate); |
void |
util_fpstate_set(unsigned fpstate); |
#ifdef __cplusplus |
} |
#endif |
#endif /* U_MATH_H */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_memory.h |
---|
0,0 → 1,100 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* 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 TUNGSTEN GRAPHICS 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. |
* |
**************************************************************************/ |
/* |
* Memory functions |
*/ |
#ifndef U_MEMORY_H |
#define U_MEMORY_H |
#include "util/u_pointer.h" |
#include "util/u_debug.h" |
#include "os/os_memory.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
#define MALLOC(_size) os_malloc(_size) |
#define CALLOC(_count, _size) os_calloc(_count, _size) |
#define FREE(_ptr ) os_free(_ptr) |
#define REALLOC(_ptr, _old_size, _size) os_realloc(_ptr, _old_size, _size) |
#define MALLOC_STRUCT(T) (struct T *) MALLOC(sizeof(struct T)) |
#define CALLOC_STRUCT(T) (struct T *) CALLOC(1, sizeof(struct T)) |
#define CALLOC_VARIANT_LENGTH_STRUCT(T,more_size) ((struct T *) CALLOC(1, sizeof(struct T) + more_size)) |
#define align_malloc(_size, _alignment) os_malloc_aligned(_size, _alignment) |
#define align_free(_ptr) os_free_aligned(_ptr) |
/** |
* Duplicate a block of memory. |
*/ |
static INLINE void * |
mem_dup(const void *src, uint size) |
{ |
void *dup = MALLOC(size); |
if (dup) |
memcpy(dup, src, size); |
return dup; |
} |
/** |
* Number of elements in an array. |
*/ |
#ifndef Elements |
#define Elements(x) (sizeof(x)/sizeof((x)[0])) |
#endif |
/** |
* Offset of a field in a struct, in bytes. |
*/ |
#define Offset(TYPE, MEMBER) ((uintptr_t)&(((TYPE *)NULL)->MEMBER)) |
#ifdef __cplusplus |
} |
#endif |
#endif /* U_MEMORY_H */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_mm.c |
---|
0,0 → 1,296 |
/************************************************************************** |
* |
* Copyright (C) 1999 Wittawat Yamwong |
* |
* 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, sublicense, |
* 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 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 NONINFRINGEMENT. IN NO EVENT SHALL |
* WITTAWAT YAMWONG, OR ANY OTHER CONTRIBUTORS 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 "pipe/p_compiler.h" |
#include "util/u_debug.h" |
#include "util/u_memory.h" |
#include "util/u_mm.h" |
void |
u_mmDumpMemInfo(const struct mem_block *heap) |
{ |
debug_printf("Memory heap %p:\n", (void *) heap); |
if (heap == 0) { |
debug_printf(" heap == 0\n"); |
} |
else { |
const struct mem_block *p; |
int total_used = 0, total_free = 0; |
for (p = heap->next; p != heap; p = p->next) { |
debug_printf(" Offset:%08x, Size:%08x, %c%c\n", p->ofs, p->size, |
p->free ? 'F':'.', |
p->reserved ? 'R':'.'); |
if (p->free) |
total_free += p->size; |
else |
total_used += p->size; |
} |
debug_printf("'\nMemory stats: total = %d, used = %d, free = %d\n", |
total_used + total_free, total_used, total_free); |
debug_printf("\nFree list:\n"); |
for (p = heap->next_free; p != heap; p = p->next_free) { |
debug_printf(" FREE Offset:%08x, Size:%08x, %c%c\n", p->ofs, p->size, |
p->free ? 'F':'.', |
p->reserved ? 'R':'.'); |
} |
} |
debug_printf("End of memory blocks\n"); |
} |
struct mem_block * |
u_mmInit(int ofs, int size) |
{ |
struct mem_block *heap, *block; |
if (size <= 0) |
return NULL; |
heap = CALLOC_STRUCT(mem_block); |
if (!heap) |
return NULL; |
block = CALLOC_STRUCT(mem_block); |
if (!block) { |
FREE(heap); |
return NULL; |
} |
heap->next = block; |
heap->prev = block; |
heap->next_free = block; |
heap->prev_free = block; |
block->heap = heap; |
block->next = heap; |
block->prev = heap; |
block->next_free = heap; |
block->prev_free = heap; |
block->ofs = ofs; |
block->size = size; |
block->free = 1; |
return heap; |
} |
static struct mem_block * |
SliceBlock(struct mem_block *p, |
int startofs, int size, |
int reserved, int alignment) |
{ |
struct mem_block *newblock; |
/* break left [p, newblock, p->next], then p = newblock */ |
if (startofs > p->ofs) { |
newblock = CALLOC_STRUCT(mem_block); |
if (!newblock) |
return NULL; |
newblock->ofs = startofs; |
newblock->size = p->size - (startofs - p->ofs); |
newblock->free = 1; |
newblock->heap = p->heap; |
newblock->next = p->next; |
newblock->prev = p; |
p->next->prev = newblock; |
p->next = newblock; |
newblock->next_free = p->next_free; |
newblock->prev_free = p; |
p->next_free->prev_free = newblock; |
p->next_free = newblock; |
p->size -= newblock->size; |
p = newblock; |
} |
/* break right, also [p, newblock, p->next] */ |
if (size < p->size) { |
newblock = CALLOC_STRUCT(mem_block); |
if (!newblock) |
return NULL; |
newblock->ofs = startofs + size; |
newblock->size = p->size - size; |
newblock->free = 1; |
newblock->heap = p->heap; |
newblock->next = p->next; |
newblock->prev = p; |
p->next->prev = newblock; |
p->next = newblock; |
newblock->next_free = p->next_free; |
newblock->prev_free = p; |
p->next_free->prev_free = newblock; |
p->next_free = newblock; |
p->size = size; |
} |
/* p = middle block */ |
p->free = 0; |
/* Remove p from the free list: |
*/ |
p->next_free->prev_free = p->prev_free; |
p->prev_free->next_free = p->next_free; |
p->next_free = 0; |
p->prev_free = 0; |
p->reserved = reserved; |
return p; |
} |
struct mem_block * |
u_mmAllocMem(struct mem_block *heap, int size, int align2, int startSearch) |
{ |
struct mem_block *p; |
const int mask = (1 << align2)-1; |
int startofs = 0; |
int endofs; |
assert(size >= 0); |
assert(align2 >= 0); |
assert(align2 <= 12); /* sanity check, 2^12 (4KB) enough? */ |
if (!heap || align2 < 0 || size <= 0) |
return NULL; |
for (p = heap->next_free; p != heap; p = p->next_free) { |
assert(p->free); |
startofs = (p->ofs + mask) & ~mask; |
if ( startofs < startSearch ) { |
startofs = startSearch; |
} |
endofs = startofs+size; |
if (endofs <= (p->ofs+p->size)) |
break; |
} |
if (p == heap) |
return NULL; |
assert(p->free); |
p = SliceBlock(p,startofs,size,0,mask+1); |
return p; |
} |
struct mem_block * |
u_mmFindBlock(struct mem_block *heap, int start) |
{ |
struct mem_block *p; |
for (p = heap->next; p != heap; p = p->next) { |
if (p->ofs == start) |
return p; |
} |
return NULL; |
} |
static INLINE int |
Join2Blocks(struct mem_block *p) |
{ |
/* XXX there should be some assertions here */ |
/* NOTE: heap->free == 0 */ |
if (p->free && p->next->free) { |
struct mem_block *q = p->next; |
assert(p->ofs + p->size == q->ofs); |
p->size += q->size; |
p->next = q->next; |
q->next->prev = p; |
q->next_free->prev_free = q->prev_free; |
q->prev_free->next_free = q->next_free; |
FREE(q); |
return 1; |
} |
return 0; |
} |
int |
u_mmFreeMem(struct mem_block *b) |
{ |
if (!b) |
return 0; |
if (b->free) { |
debug_printf("block already free\n"); |
return -1; |
} |
if (b->reserved) { |
debug_printf("block is reserved\n"); |
return -1; |
} |
b->free = 1; |
b->next_free = b->heap->next_free; |
b->prev_free = b->heap; |
b->next_free->prev_free = b; |
b->prev_free->next_free = b; |
Join2Blocks(b); |
if (b->prev != b->heap) |
Join2Blocks(b->prev); |
return 0; |
} |
void |
u_mmDestroy(struct mem_block *heap) |
{ |
struct mem_block *p; |
if (!heap) |
return; |
for (p = heap->next; p != heap; ) { |
struct mem_block *next = p->next; |
FREE(p); |
p = next; |
} |
FREE(heap); |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_mm.h |
---|
0,0 → 1,91 |
/************************************************************************** |
* |
* Copyright (C) 1999 Wittawat Yamwong |
* |
* 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, sublicense, |
* 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 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 NONINFRINGEMENT. IN NO EVENT SHALL |
* KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS 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. |
* |
**************************************************************************/ |
/** |
* @file |
* Memory manager code. Primarily used by device drivers to manage texture |
* heaps, etc. |
*/ |
#ifndef _U_MM_H_ |
#define _U_MM_H_ |
struct mem_block { |
struct mem_block *next, *prev; |
struct mem_block *next_free, *prev_free; |
struct mem_block *heap; |
int ofs,size; |
unsigned int free:1; |
unsigned int reserved:1; |
}; |
/** |
* input: total size in bytes |
* return: a heap pointer if OK, NULL if error |
*/ |
extern struct mem_block *u_mmInit(int ofs, int size); |
/** |
* Allocate 'size' bytes with 2^align2 bytes alignment, |
* restrict the search to free memory after 'startSearch' |
* depth and back buffers should be in different 4mb banks |
* to get better page hits if possible |
* input: size = size of block |
* align2 = 2^align2 bytes alignment |
* startSearch = linear offset from start of heap to begin search |
* return: pointer to the allocated block, 0 if error |
*/ |
extern struct mem_block *u_mmAllocMem(struct mem_block *heap, int size, int align2, |
int startSearch); |
/** |
* Free block starts at offset |
* input: pointer to a block |
* return: 0 if OK, -1 if error |
*/ |
extern int u_mmFreeMem(struct mem_block *b); |
/** |
* Free block starts at offset |
* input: pointer to a heap, start offset |
* return: pointer to a block |
*/ |
extern struct mem_block *u_mmFindBlock(struct mem_block *heap, int start); |
/** |
* destroy MM |
*/ |
extern void u_mmDestroy(struct mem_block *mmInit); |
/** |
* For debugging purposes. |
*/ |
extern void u_mmDumpMemInfo(const struct mem_block *mmInit); |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_network.c |
---|
0,0 → 1,191 |
#include "pipe/p_compiler.h" |
#include "util/u_network.h" |
#include "util/u_debug.h" |
#if defined(PIPE_SUBSYSTEM_WINDOWS_USER) |
# include <winsock2.h> |
# include <windows.h> |
#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || \ |
defined(PIPE_OS_APPLE) || defined(PIPE_OS_CYGWIN) || defined(PIPE_OS_SOLARIS) |
# include <sys/socket.h> |
# include <netinet/in.h> |
# include <unistd.h> |
# include <fcntl.h> |
# include <netdb.h> |
#else |
# warning "No socket implementation" |
#endif |
boolean |
u_socket_init() |
{ |
#if defined(PIPE_SUBSYSTEM_WINDOWS_USER) |
WORD wVersionRequested; |
WSADATA wsaData; |
int err; |
/* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */ |
wVersionRequested = MAKEWORD(1, 1); |
err = WSAStartup(wVersionRequested, &wsaData); |
if (err != 0) { |
debug_printf("WSAStartup failed with error: %d\n", err); |
return FALSE; |
} |
return TRUE; |
#elif defined(PIPE_HAVE_SOCKETS) |
return TRUE; |
#else |
return FALSE; |
#endif |
} |
void |
u_socket_stop() |
{ |
#if defined(PIPE_SUBSYSTEM_WINDOWS_USER) |
WSACleanup(); |
#endif |
} |
void |
u_socket_close(int s) |
{ |
if (s < 0) |
return; |
#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) \ |
|| defined(PIPE_OS_APPLE) || defined(PIPE_OS_SOLARIS) |
shutdown(s, SHUT_RDWR); |
close(s); |
#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) |
shutdown(s, SD_BOTH); |
closesocket(s); |
#else |
assert(0); |
#endif |
} |
int u_socket_accept(int s) |
{ |
#if defined(PIPE_HAVE_SOCKETS) |
return accept(s, NULL, NULL); |
#else |
return -1; |
#endif |
} |
int |
u_socket_send(int s, void *data, size_t size) |
{ |
#if defined(PIPE_HAVE_SOCKETS) |
return send(s, data, size, 0); |
#else |
return -1; |
#endif |
} |
int |
u_socket_peek(int s, void *data, size_t size) |
{ |
#if defined(PIPE_HAVE_SOCKETS) |
return recv(s, data, size, MSG_PEEK); |
#else |
return -1; |
#endif |
} |
int |
u_socket_recv(int s, void *data, size_t size) |
{ |
#if defined(PIPE_HAVE_SOCKETS) |
return recv(s, data, size, 0); |
#else |
return -1; |
#endif |
} |
int |
u_socket_connect(const char *hostname, uint16_t port) |
{ |
#if defined(PIPE_HAVE_SOCKETS) |
int s; |
struct sockaddr_in sa; |
struct hostent *host = NULL; |
memset(&sa, 0, sizeof(struct sockaddr_in)); |
host = gethostbyname(hostname); |
if (!host) |
return -1; |
memcpy((char *)&sa.sin_addr,host->h_addr_list[0],host->h_length); |
sa.sin_family= host->h_addrtype; |
sa.sin_port = htons(port); |
s = socket(host->h_addrtype, SOCK_STREAM, IPPROTO_TCP); |
if (s < 0) |
return -1; |
if (connect(s, (struct sockaddr *)&sa, sizeof(sa))) { |
u_socket_close(s); |
return -1; |
} |
return s; |
#else |
assert(0); |
return -1; |
#endif |
} |
int |
u_socket_listen_on_port(uint16_t portnum) |
{ |
#if defined(PIPE_HAVE_SOCKETS) |
int s; |
struct sockaddr_in sa; |
memset(&sa, 0, sizeof(struct sockaddr_in)); |
sa.sin_family = AF_INET; |
sa.sin_port = htons(portnum); |
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); |
if (s < 0) |
return -1; |
if (bind(s, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) == -1) { |
u_socket_close(s); |
return -1; |
} |
listen(s, 0); |
return s; |
#else |
assert(0); |
return -1; |
#endif |
} |
void |
u_socket_block(int s, boolean block) |
{ |
#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) \ |
|| defined(PIPE_OS_APPLE) || defined(PIPE_OS_SOLARIS) |
int old = fcntl(s, F_GETFL, 0); |
if (old == -1) |
return; |
/* TODO obey block */ |
if (block) |
fcntl(s, F_SETFL, old & ~O_NONBLOCK); |
else |
fcntl(s, F_SETFL, old | O_NONBLOCK); |
#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) |
u_long iMode = block ? 0 : 1; |
ioctlsocket(s, FIONBIO, &iMode); |
#else |
assert(0); |
#endif |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_network.h |
---|
0,0 → 1,25 |
#ifndef _U_NETWORK_H_ |
#define _U_NETWORK_H_ |
#include "pipe/p_compiler.h" |
#if defined(PIPE_SUBSYSTEM_WINDOWS_USER) |
# define PIPE_HAVE_SOCKETS |
#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || \ |
defined(PIPE_OS_APPLE) || defined(PIPE_OS_SOLARIS) |
# define PIPE_HAVE_SOCKETS |
#endif |
boolean u_socket_init(void); |
void u_socket_stop(void); |
void u_socket_close(int s); |
int u_socket_listen_on_port(uint16_t portnum); |
int u_socket_accept(int s); |
int u_socket_connect(const char *host, uint16_t port); |
int u_socket_send(int s, void *data, size_t size); |
int u_socket_peek(int s, void *data, size_t size); |
int u_socket_recv(int s, void *data, size_t size); |
void u_socket_block(int s, boolean block); |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_pack_color.h |
---|
0,0 → 1,651 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* 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 TUNGSTEN GRAPHICS 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. |
* |
**************************************************************************/ |
/** |
* @file |
* Functions to produce packed colors/Z from floats. |
*/ |
#ifndef U_PACK_COLOR_H |
#define U_PACK_COLOR_H |
#include "pipe/p_compiler.h" |
#include "pipe/p_format.h" |
#include "util/u_debug.h" |
#include "util/u_format.h" |
#include "util/u_math.h" |
/** |
* Helper union for packing pixel values. |
* Will often contain values in formats which are too complex to be described |
* in simple terms, hence might just effectively contain a number of bytes. |
* Must be big enough to hold data for all formats (currently 256 bits). |
*/ |
union util_color { |
ubyte ub; |
ushort us; |
uint ui; |
ushort h[4]; /* half float */ |
float f[4]; |
double d[4]; |
}; |
/** |
* Pack ubyte R,G,B,A into dest pixel. |
*/ |
static INLINE void |
util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a, |
enum pipe_format format, union util_color *uc) |
{ |
switch (format) { |
case PIPE_FORMAT_ABGR8888_UNORM: |
{ |
uc->ui = (r << 24) | (g << 16) | (b << 8) | a; |
} |
return; |
case PIPE_FORMAT_XBGR8888_UNORM: |
{ |
uc->ui = (r << 24) | (g << 16) | (b << 8) | 0xff; |
} |
return; |
case PIPE_FORMAT_BGRA8888_UNORM: |
{ |
uc->ui = (a << 24) | (r << 16) | (g << 8) | b; |
} |
return; |
case PIPE_FORMAT_BGRX8888_UNORM: |
{ |
uc->ui = (0xff << 24) | (r << 16) | (g << 8) | b; |
} |
return; |
case PIPE_FORMAT_ARGB8888_UNORM: |
{ |
uc->ui = (b << 24) | (g << 16) | (r << 8) | a; |
} |
return; |
case PIPE_FORMAT_XRGB8888_UNORM: |
{ |
uc->ui = (b << 24) | (g << 16) | (r << 8) | 0xff; |
} |
return; |
case PIPE_FORMAT_B5G6R5_UNORM: |
{ |
uc->us = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3); |
} |
return; |
case PIPE_FORMAT_B5G5R5X1_UNORM: |
{ |
uc->us = ((0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3); |
} |
return; |
case PIPE_FORMAT_B5G5R5A1_UNORM: |
{ |
uc->us = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3); |
} |
return; |
case PIPE_FORMAT_B4G4R4A4_UNORM: |
{ |
uc->us = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4); |
} |
return; |
case PIPE_FORMAT_A8_UNORM: |
{ |
uc->ub = a; |
} |
return; |
case PIPE_FORMAT_L8_UNORM: |
case PIPE_FORMAT_I8_UNORM: |
{ |
uc->ub = r; |
} |
return; |
case PIPE_FORMAT_R32G32B32A32_FLOAT: |
{ |
uc->f[0] = (float)r / 255.0f; |
uc->f[1] = (float)g / 255.0f; |
uc->f[2] = (float)b / 255.0f; |
uc->f[3] = (float)a / 255.0f; |
} |
return; |
case PIPE_FORMAT_R32G32B32_FLOAT: |
{ |
uc->f[0] = (float)r / 255.0f; |
uc->f[1] = (float)g / 255.0f; |
uc->f[2] = (float)b / 255.0f; |
} |
return; |
/* Handle other cases with a generic function. |
*/ |
default: |
{ |
ubyte src[4]; |
src[0] = r; |
src[1] = g; |
src[2] = b; |
src[3] = a; |
util_format_write_4ub(format, src, 0, uc, 0, 0, 0, 1, 1); |
} |
} |
} |
/** |
* Unpack RGBA from a packed pixel, returning values as ubytes in [0,255]. |
*/ |
static INLINE void |
util_unpack_color_ub(enum pipe_format format, union util_color *uc, |
ubyte *r, ubyte *g, ubyte *b, ubyte *a) |
{ |
switch (format) { |
case PIPE_FORMAT_ABGR8888_UNORM: |
{ |
uint p = uc->ui; |
*r = (ubyte) ((p >> 24) & 0xff); |
*g = (ubyte) ((p >> 16) & 0xff); |
*b = (ubyte) ((p >> 8) & 0xff); |
*a = (ubyte) ((p >> 0) & 0xff); |
} |
return; |
case PIPE_FORMAT_XBGR8888_UNORM: |
{ |
uint p = uc->ui; |
*r = (ubyte) ((p >> 24) & 0xff); |
*g = (ubyte) ((p >> 16) & 0xff); |
*b = (ubyte) ((p >> 8) & 0xff); |
*a = (ubyte) 0xff; |
} |
return; |
case PIPE_FORMAT_BGRA8888_UNORM: |
{ |
uint p = uc->ui; |
*r = (ubyte) ((p >> 16) & 0xff); |
*g = (ubyte) ((p >> 8) & 0xff); |
*b = (ubyte) ((p >> 0) & 0xff); |
*a = (ubyte) ((p >> 24) & 0xff); |
} |
return; |
case PIPE_FORMAT_BGRX8888_UNORM: |
{ |
uint p = uc->ui; |
*r = (ubyte) ((p >> 16) & 0xff); |
*g = (ubyte) ((p >> 8) & 0xff); |
*b = (ubyte) ((p >> 0) & 0xff); |
*a = (ubyte) 0xff; |
} |
return; |
case PIPE_FORMAT_ARGB8888_UNORM: |
{ |
uint p = uc->ui; |
*r = (ubyte) ((p >> 8) & 0xff); |
*g = (ubyte) ((p >> 16) & 0xff); |
*b = (ubyte) ((p >> 24) & 0xff); |
*a = (ubyte) ((p >> 0) & 0xff); |
} |
return; |
case PIPE_FORMAT_XRGB8888_UNORM: |
{ |
uint p = uc->ui; |
*r = (ubyte) ((p >> 8) & 0xff); |
*g = (ubyte) ((p >> 16) & 0xff); |
*b = (ubyte) ((p >> 24) & 0xff); |
*a = (ubyte) 0xff; |
} |
return; |
case PIPE_FORMAT_B5G6R5_UNORM: |
{ |
ushort p = uc->us; |
*r = (ubyte) (((p >> 8) & 0xf8) | ((p >> 13) & 0x7)); |
*g = (ubyte) (((p >> 3) & 0xfc) | ((p >> 9) & 0x3)); |
*b = (ubyte) (((p << 3) & 0xf8) | ((p >> 2) & 0x7)); |
*a = (ubyte) 0xff; |
} |
return; |
case PIPE_FORMAT_B5G5R5X1_UNORM: |
{ |
ushort p = uc->us; |
*r = (ubyte) (((p >> 7) & 0xf8) | ((p >> 12) & 0x7)); |
*g = (ubyte) (((p >> 2) & 0xf8) | ((p >> 7) & 0x7)); |
*b = (ubyte) (((p << 3) & 0xf8) | ((p >> 2) & 0x7)); |
*a = (ubyte) 0xff; |
} |
return; |
case PIPE_FORMAT_B5G5R5A1_UNORM: |
{ |
ushort p = uc->us; |
*r = (ubyte) (((p >> 7) & 0xf8) | ((p >> 12) & 0x7)); |
*g = (ubyte) (((p >> 2) & 0xf8) | ((p >> 7) & 0x7)); |
*b = (ubyte) (((p << 3) & 0xf8) | ((p >> 2) & 0x7)); |
*a = (ubyte) (0xff * (p >> 15)); |
} |
return; |
case PIPE_FORMAT_B4G4R4A4_UNORM: |
{ |
ushort p = uc->us; |
*r = (ubyte) (((p >> 4) & 0xf0) | ((p >> 8) & 0xf)); |
*g = (ubyte) (((p >> 0) & 0xf0) | ((p >> 4) & 0xf)); |
*b = (ubyte) (((p << 4) & 0xf0) | ((p >> 0) & 0xf)); |
*a = (ubyte) (((p >> 8) & 0xf0) | ((p >> 12) & 0xf)); |
} |
return; |
case PIPE_FORMAT_A8_UNORM: |
{ |
ubyte p = uc->ub; |
*r = *g = *b = (ubyte) 0xff; |
*a = p; |
} |
return; |
case PIPE_FORMAT_L8_UNORM: |
{ |
ubyte p = uc->ub; |
*r = *g = *b = p; |
*a = (ubyte) 0xff; |
} |
return; |
case PIPE_FORMAT_I8_UNORM: |
{ |
ubyte p = uc->ub; |
*r = *g = *b = *a = p; |
} |
return; |
case PIPE_FORMAT_R32G32B32A32_FLOAT: |
{ |
const float *p = &uc->f[0]; |
*r = float_to_ubyte(p[0]); |
*g = float_to_ubyte(p[1]); |
*b = float_to_ubyte(p[2]); |
*a = float_to_ubyte(p[3]); |
} |
return; |
case PIPE_FORMAT_R32G32B32_FLOAT: |
{ |
const float *p = &uc->f[0]; |
*r = float_to_ubyte(p[0]); |
*g = float_to_ubyte(p[1]); |
*b = float_to_ubyte(p[2]); |
*a = (ubyte) 0xff; |
} |
return; |
case PIPE_FORMAT_R32G32_FLOAT: |
{ |
const float *p = &uc->f[0]; |
*r = float_to_ubyte(p[0]); |
*g = float_to_ubyte(p[1]); |
*b = *a = (ubyte) 0xff; |
} |
return; |
case PIPE_FORMAT_R32_FLOAT: |
{ |
const float *p = &uc->f[0]; |
*r = float_to_ubyte(p[0]); |
*g = *b = *a = (ubyte) 0xff; |
} |
return; |
/* Handle other cases with a generic function. |
*/ |
default: |
{ |
ubyte dst[4]; |
util_format_read_4ub(format, dst, 0, uc, 0, 0, 0, 1, 1); |
*r = dst[0]; |
*g = dst[1]; |
*b = dst[2]; |
*a = dst[3]; |
} |
} |
} |
/** |
* Note rgba outside [0,1] will be clamped for int pixel formats. |
* This will not work (and might not really be useful with float input) |
* for pure integer formats (which lack the pack_rgba_float function). |
*/ |
static INLINE void |
util_pack_color(const float rgba[4], enum pipe_format format, union util_color *uc) |
{ |
ubyte r = 0; |
ubyte g = 0; |
ubyte b = 0; |
ubyte a = 0; |
if (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0) <= 8) { |
/* format uses 8-bit components or less */ |
r = float_to_ubyte(rgba[0]); |
g = float_to_ubyte(rgba[1]); |
b = float_to_ubyte(rgba[2]); |
a = float_to_ubyte(rgba[3]); |
} |
switch (format) { |
case PIPE_FORMAT_ABGR8888_UNORM: |
{ |
uc->ui = (r << 24) | (g << 16) | (b << 8) | a; |
} |
return; |
case PIPE_FORMAT_XBGR8888_UNORM: |
{ |
uc->ui = (r << 24) | (g << 16) | (b << 8) | 0xff; |
} |
return; |
case PIPE_FORMAT_BGRA8888_UNORM: |
{ |
uc->ui = (a << 24) | (r << 16) | (g << 8) | b; |
} |
return; |
case PIPE_FORMAT_BGRX8888_UNORM: |
{ |
uc->ui = (0xff << 24) | (r << 16) | (g << 8) | b; |
} |
return; |
case PIPE_FORMAT_ARGB8888_UNORM: |
{ |
uc->ui = (b << 24) | (g << 16) | (r << 8) | a; |
} |
return; |
case PIPE_FORMAT_XRGB8888_UNORM: |
{ |
uc->ui = (b << 24) | (g << 16) | (r << 8) | 0xff; |
} |
return; |
case PIPE_FORMAT_B5G6R5_UNORM: |
{ |
uc->us = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3); |
} |
return; |
case PIPE_FORMAT_B5G5R5X1_UNORM: |
{ |
uc->us = ((0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3); |
} |
return; |
case PIPE_FORMAT_B5G5R5A1_UNORM: |
{ |
uc->us = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3); |
} |
return; |
case PIPE_FORMAT_B4G4R4A4_UNORM: |
{ |
uc->us = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4); |
} |
return; |
case PIPE_FORMAT_A8_UNORM: |
{ |
uc->ub = a; |
} |
return; |
case PIPE_FORMAT_L8_UNORM: |
case PIPE_FORMAT_I8_UNORM: |
{ |
uc->ub = r; |
} |
return; |
case PIPE_FORMAT_R32G32B32A32_FLOAT: |
{ |
uc->f[0] = rgba[0]; |
uc->f[1] = rgba[1]; |
uc->f[2] = rgba[2]; |
uc->f[3] = rgba[3]; |
} |
return; |
case PIPE_FORMAT_R32G32B32_FLOAT: |
{ |
uc->f[0] = rgba[0]; |
uc->f[1] = rgba[1]; |
uc->f[2] = rgba[2]; |
} |
return; |
/* Handle other cases with a generic function. |
*/ |
default: |
util_format_write_4f(format, rgba, 0, uc, 0, 0, 0, 1, 1); |
} |
} |
/* Integer versions of util_pack_z and util_pack_z_stencil - useful for |
* constructing clear masks. |
*/ |
static INLINE uint32_t |
util_pack_mask_z(enum pipe_format format, uint32_t z) |
{ |
switch (format) { |
case PIPE_FORMAT_Z16_UNORM: |
return z & 0xffff; |
case PIPE_FORMAT_Z32_UNORM: |
case PIPE_FORMAT_Z32_FLOAT: |
return z; |
case PIPE_FORMAT_Z24_UNORM_S8_UINT: |
case PIPE_FORMAT_Z24X8_UNORM: |
return z & 0xffffff; |
case PIPE_FORMAT_S8_UINT_Z24_UNORM: |
case PIPE_FORMAT_X8Z24_UNORM: |
return (z & 0xffffff) << 8; |
case PIPE_FORMAT_S8_UINT: |
return 0; |
default: |
debug_print_format("gallium: unhandled format in util_pack_mask_z()", format); |
assert(0); |
return 0; |
} |
} |
static INLINE uint64_t |
util_pack64_mask_z(enum pipe_format format, uint32_t z) |
{ |
switch (format) { |
case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: |
return z; |
default: |
return util_pack_mask_z(format, z); |
} |
} |
static INLINE uint32_t |
util_pack_mask_z_stencil(enum pipe_format format, uint32_t z, uint8_t s) |
{ |
uint32_t packed = util_pack_mask_z(format, z); |
switch (format) { |
case PIPE_FORMAT_Z24_UNORM_S8_UINT: |
packed |= (uint32_t)s << 24; |
break; |
case PIPE_FORMAT_S8_UINT_Z24_UNORM: |
packed |= s; |
break; |
case PIPE_FORMAT_S8_UINT: |
packed |= s; |
break; |
default: |
break; |
} |
return packed; |
} |
static INLINE uint64_t |
util_pack64_mask_z_stencil(enum pipe_format format, uint32_t z, uint8_t s) |
{ |
uint64_t packed; |
switch (format) { |
case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: |
packed = util_pack64_mask_z(format, z); |
packed |= (uint64_t)s << 32ull; |
return packed; |
default: |
return util_pack_mask_z_stencil(format, z, s); |
} |
} |
/** |
* Note: it's assumed that z is in [0,1] |
*/ |
static INLINE uint32_t |
util_pack_z(enum pipe_format format, double z) |
{ |
union fi fui; |
if (z == 0.0) |
return 0; |
switch (format) { |
case PIPE_FORMAT_Z16_UNORM: |
if (z == 1.0) |
return 0xffff; |
return (uint32_t) (z * 0xffff); |
case PIPE_FORMAT_Z32_UNORM: |
/* special-case to avoid overflow */ |
if (z == 1.0) |
return 0xffffffff; |
return (uint32_t) (z * 0xffffffff); |
case PIPE_FORMAT_Z32_FLOAT: |
fui.f = (float)z; |
return fui.ui; |
case PIPE_FORMAT_Z24_UNORM_S8_UINT: |
case PIPE_FORMAT_Z24X8_UNORM: |
if (z == 1.0) |
return 0xffffff; |
return (uint32_t) (z * 0xffffff); |
case PIPE_FORMAT_S8_UINT_Z24_UNORM: |
case PIPE_FORMAT_X8Z24_UNORM: |
if (z == 1.0) |
return 0xffffff00; |
return ((uint32_t) (z * 0xffffff)) << 8; |
case PIPE_FORMAT_S8_UINT: |
/* this case can get it via util_pack_z_stencil() */ |
return 0; |
default: |
debug_print_format("gallium: unhandled format in util_pack_z()", format); |
assert(0); |
return 0; |
} |
} |
static INLINE uint64_t |
util_pack64_z(enum pipe_format format, double z) |
{ |
union fi fui; |
if (z == 0) |
return 0; |
switch (format) { |
case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: |
fui.f = (float)z; |
return fui.ui; |
default: |
return util_pack_z(format, z); |
} |
} |
/** |
* Pack Z and/or stencil values into a 32-bit value described by format. |
* Note: it's assumed that z is in [0,1] and s in [0,255] |
*/ |
static INLINE uint32_t |
util_pack_z_stencil(enum pipe_format format, double z, uint8_t s) |
{ |
uint32_t packed = util_pack_z(format, z); |
switch (format) { |
case PIPE_FORMAT_Z24_UNORM_S8_UINT: |
packed |= (uint32_t)s << 24; |
break; |
case PIPE_FORMAT_S8_UINT_Z24_UNORM: |
packed |= s; |
break; |
case PIPE_FORMAT_S8_UINT: |
packed |= s; |
break; |
default: |
break; |
} |
return packed; |
} |
static INLINE uint64_t |
util_pack64_z_stencil(enum pipe_format format, double z, uint8_t s) |
{ |
uint64_t packed; |
switch (format) { |
case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: |
packed = util_pack64_z(format, z); |
packed |= (uint64_t)s << 32ull; |
break; |
default: |
return util_pack_z_stencil(format, z, s); |
} |
return packed; |
} |
/** |
* Pack 4 ubytes into a 4-byte word |
*/ |
static INLINE unsigned |
pack_ub4(ubyte b0, ubyte b1, ubyte b2, ubyte b3) |
{ |
return ((((unsigned int)b0) << 0) | |
(((unsigned int)b1) << 8) | |
(((unsigned int)b2) << 16) | |
(((unsigned int)b3) << 24)); |
} |
/** |
* Pack/convert 4 floats into one 4-byte word. |
*/ |
static INLINE unsigned |
pack_ui32_float4(float a, float b, float c, float d) |
{ |
return pack_ub4( float_to_ubyte(a), |
float_to_ubyte(b), |
float_to_ubyte(c), |
float_to_ubyte(d) ); |
} |
#endif /* U_PACK_COLOR_H */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_pointer.h |
---|
0,0 → 1,130 |
/************************************************************************** |
* |
* Copyright 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* 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 TUNGSTEN GRAPHICS 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_POINTER_H |
#define U_POINTER_H |
#include "pipe/p_compiler.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
static INLINE intptr_t |
pointer_to_intptr( const void *p ) |
{ |
union { |
const void *p; |
intptr_t i; |
} pi; |
pi.p = p; |
return pi.i; |
} |
static INLINE void * |
intptr_to_pointer( intptr_t i ) |
{ |
union { |
void *p; |
intptr_t i; |
} pi; |
pi.i = i; |
return pi.p; |
} |
static INLINE uintptr_t |
pointer_to_uintptr( const void *ptr ) |
{ |
union { |
const void *p; |
uintptr_t u; |
} pu; |
pu.p = ptr; |
return pu.u; |
} |
static INLINE void * |
uintptr_to_pointer( uintptr_t u ) |
{ |
union { |
void *p; |
uintptr_t u; |
} pu; |
pu.u = u; |
return pu.p; |
} |
/** |
* Return a pointer aligned to next multiple of N bytes. |
*/ |
static INLINE void * |
align_pointer( const void *unaligned, uintptr_t alignment ) |
{ |
uintptr_t aligned = (pointer_to_uintptr( unaligned ) + alignment - 1) & ~(alignment - 1); |
return uintptr_to_pointer( aligned ); |
} |
/** |
* Return a pointer aligned to next multiple of 16 bytes. |
*/ |
static INLINE void * |
align16( void *unaligned ) |
{ |
return align_pointer( unaligned, 16 ); |
} |
typedef void (*func_pointer)(void); |
static INLINE func_pointer |
pointer_to_func( void *p ) |
{ |
union { |
void *p; |
func_pointer f; |
} pf; |
pf.p = p; |
return pf.f; |
} |
static INLINE void * |
func_to_pointer( func_pointer f ) |
{ |
union { |
void *p; |
func_pointer f; |
} pf; |
pf.f = f; |
return pf.p; |
} |
#ifdef __cplusplus |
} |
#endif |
#endif /* U_POINTER_H */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_prim.h |
---|
0,0 → 1,268 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* 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 TUNGSTEN GRAPHICS 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_PRIM_H |
#define U_PRIM_H |
#include "pipe/p_defines.h" |
#include "util/u_debug.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
struct u_prim_vertex_count { |
unsigned min; |
unsigned incr; |
}; |
/** |
* Decompose a primitive that is a loop, a strip, or a fan. Return the |
* original primitive if it is already decomposed. |
*/ |
static INLINE unsigned |
u_decomposed_prim(unsigned prim) |
{ |
switch (prim) { |
case PIPE_PRIM_LINE_LOOP: |
case PIPE_PRIM_LINE_STRIP: |
return PIPE_PRIM_LINES; |
case PIPE_PRIM_TRIANGLE_STRIP: |
case PIPE_PRIM_TRIANGLE_FAN: |
return PIPE_PRIM_TRIANGLES; |
case PIPE_PRIM_QUAD_STRIP: |
return PIPE_PRIM_QUADS; |
case PIPE_PRIM_LINE_STRIP_ADJACENCY: |
return PIPE_PRIM_LINES_ADJACENCY; |
case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: |
return PIPE_PRIM_TRIANGLES_ADJACENCY; |
default: |
return prim; |
} |
} |
/** |
* Reduce a primitive to one of PIPE_PRIM_POINTS, PIPE_PRIM_LINES, and |
* PIPE_PRIM_TRIANGLES. |
*/ |
static INLINE unsigned |
u_reduced_prim(unsigned prim) |
{ |
switch (prim) { |
case PIPE_PRIM_POINTS: |
return PIPE_PRIM_POINTS; |
case PIPE_PRIM_LINES: |
case PIPE_PRIM_LINE_LOOP: |
case PIPE_PRIM_LINE_STRIP: |
case PIPE_PRIM_LINES_ADJACENCY: |
case PIPE_PRIM_LINE_STRIP_ADJACENCY: |
return PIPE_PRIM_LINES; |
default: |
return PIPE_PRIM_TRIANGLES; |
} |
} |
/** |
* Re-assemble a primitive to remove its adjacency. |
*/ |
static INLINE unsigned |
u_assembled_prim(unsigned prim) |
{ |
switch (prim) { |
case PIPE_PRIM_LINES_ADJACENCY: |
case PIPE_PRIM_LINE_STRIP_ADJACENCY: |
return PIPE_PRIM_LINES; |
case PIPE_PRIM_TRIANGLES_ADJACENCY: |
case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: |
return PIPE_PRIM_TRIANGLES; |
default: |
return prim; |
} |
} |
/** |
* Return the vertex count information for a primitive. |
* |
* Note that if this function is called directly or indirectly anywhere in a |
* source file, it will increase the size of the binary slightly more than |
* expected because of the use of a table. |
*/ |
static INLINE const struct u_prim_vertex_count * |
u_prim_vertex_count(unsigned prim) |
{ |
static const struct u_prim_vertex_count prim_table[PIPE_PRIM_MAX] = { |
{ 1, 1 }, /* PIPE_PRIM_POINTS */ |
{ 2, 2 }, /* PIPE_PRIM_LINES */ |
{ 2, 1 }, /* PIPE_PRIM_LINE_LOOP */ |
{ 2, 1 }, /* PIPE_PRIM_LINE_STRIP */ |
{ 3, 3 }, /* PIPE_PRIM_TRIANGLES */ |
{ 3, 1 }, /* PIPE_PRIM_TRIANGLE_STRIP */ |
{ 3, 1 }, /* PIPE_PRIM_TRIANGLE_FAN */ |
{ 4, 4 }, /* PIPE_PRIM_QUADS */ |
{ 4, 2 }, /* PIPE_PRIM_QUAD_STRIP */ |
{ 3, 1 }, /* PIPE_PRIM_POLYGON */ |
{ 4, 4 }, /* PIPE_PRIM_LINES_ADJACENCY */ |
{ 4, 1 }, /* PIPE_PRIM_LINE_STRIP_ADJACENCY */ |
{ 6, 6 }, /* PIPE_PRIM_TRIANGLES_ADJACENCY */ |
{ 6, 2 }, /* PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY */ |
}; |
return (likely(prim < PIPE_PRIM_MAX)) ? &prim_table[prim] : NULL; |
} |
static INLINE boolean u_validate_pipe_prim( unsigned pipe_prim, unsigned nr ) |
{ |
const struct u_prim_vertex_count *count = u_prim_vertex_count(pipe_prim); |
return (count && nr >= count->min); |
} |
static INLINE boolean u_trim_pipe_prim( unsigned pipe_prim, unsigned *nr ) |
{ |
const struct u_prim_vertex_count *count = u_prim_vertex_count(pipe_prim); |
if (count && *nr >= count->min) { |
if (count->incr > 1) |
*nr -= (*nr % count->incr); |
return TRUE; |
} |
else { |
*nr = 0; |
return FALSE; |
} |
} |
static INLINE unsigned |
u_vertices_per_prim(int primitive) |
{ |
switch(primitive) { |
case PIPE_PRIM_POINTS: |
return 1; |
case PIPE_PRIM_LINES: |
case PIPE_PRIM_LINE_LOOP: |
case PIPE_PRIM_LINE_STRIP: |
return 2; |
case PIPE_PRIM_TRIANGLES: |
case PIPE_PRIM_TRIANGLE_STRIP: |
case PIPE_PRIM_TRIANGLE_FAN: |
return 3; |
case PIPE_PRIM_LINES_ADJACENCY: |
case PIPE_PRIM_LINE_STRIP_ADJACENCY: |
return 4; |
case PIPE_PRIM_TRIANGLES_ADJACENCY: |
case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: |
return 6; |
/* following primitives should never be used |
* with geometry shaders abd their size is |
* undefined */ |
case PIPE_PRIM_POLYGON: |
case PIPE_PRIM_QUADS: |
case PIPE_PRIM_QUAD_STRIP: |
default: |
debug_printf("Unrecognized geometry shader primitive"); |
return 3; |
} |
} |
/** |
* Returns the number of decomposed primitives for the given |
* vertex count. |
* Parts of the pipline are invoked once for each triangle in |
* triangle strip, triangle fans and triangles and once |
* for each line in line strip, line loop, lines. Also |
* statistics depend on knowing the exact number of decomposed |
* primitives for a set of vertices. |
*/ |
static INLINE unsigned |
u_decomposed_prims_for_vertices(int primitive, int vertices) |
{ |
switch (primitive) { |
case PIPE_PRIM_POINTS: |
return vertices; |
case PIPE_PRIM_LINES: |
return vertices / 2; |
case PIPE_PRIM_LINE_LOOP: |
return (vertices >= 2) ? vertices : 0; |
case PIPE_PRIM_LINE_STRIP: |
return (vertices >= 2) ? vertices - 1 : 0; |
case PIPE_PRIM_TRIANGLES: |
return vertices / 3; |
case PIPE_PRIM_TRIANGLE_STRIP: |
return (vertices >= 3) ? vertices - 2 : 0; |
case PIPE_PRIM_TRIANGLE_FAN: |
return (vertices >= 3) ? vertices - 2 : 0; |
case PIPE_PRIM_LINES_ADJACENCY: |
return vertices / 4; |
case PIPE_PRIM_LINE_STRIP_ADJACENCY: |
return (vertices >= 4) ? vertices - 3 : 0; |
case PIPE_PRIM_TRIANGLES_ADJACENCY: |
return vertices / 6; |
case PIPE_PRIM_TRIANGLE_STRIP_ADJACENCY: |
return (vertices >= 6) ? 1 + (vertices - 6) / 2 : 0; |
case PIPE_PRIM_QUADS: |
return vertices / 4; |
case PIPE_PRIM_QUAD_STRIP: |
return (vertices >= 4) ? (vertices - 2) / 2 : 0; |
/* Polygons can't be decomposed |
* because the number of their vertices isn't known so |
* for them and whatever else we don't recognize just |
* return 1 if the number of vertices is greater than |
* or equal to 3 and zero otherwise */ |
case PIPE_PRIM_POLYGON: |
default: |
debug_printf("Invalid decomposition primitive!\n"); |
return (vertices >= 3) ? 1 : 0; |
} |
} |
/** |
* Returns the number of reduced/tessellated primitives for the given vertex |
* count. Each quad is treated as two triangles. Polygons are treated as |
* triangle fans. |
*/ |
static INLINE unsigned |
u_reduced_prims_for_vertices(int primitive, int vertices) |
{ |
switch (primitive) { |
case PIPE_PRIM_QUADS: |
case PIPE_PRIM_QUAD_STRIP: |
return u_decomposed_prims_for_vertices(primitive, vertices) * 2; |
case PIPE_PRIM_POLYGON: |
primitive = PIPE_PRIM_TRIANGLE_FAN; |
/* fall through */ |
default: |
return u_decomposed_prims_for_vertices(primitive, vertices); |
} |
} |
const char *u_prim_name( unsigned pipe_prim ); |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_pstipple.c |
---|
0,0 → 1,456 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* Copyright 2010 VMware, Inc. |
* 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 TUNGSTEN GRAPHICS 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. |
* |
**************************************************************************/ |
/** |
* Polygon stipple helper module. Drivers/GPUs which don't support polygon |
* stipple natively can use this module to simulate it. |
* |
* Basically, modify fragment shader to sample the 32x32 stipple pattern |
* texture and do a fragment kill for the 'off' bits. |
* |
* This was originally a 'draw' module stage, but since we don't need |
* vertex window coords or anything, it can be a stand-alone utility module. |
* |
* Authors: Brian Paul |
*/ |
#include "pipe/p_context.h" |
#include "pipe/p_defines.h" |
#include "pipe/p_shader_tokens.h" |
#include "util/u_inlines.h" |
#include "util/u_format.h" |
#include "util/u_memory.h" |
#include "util/u_pstipple.h" |
#include "util/u_sampler.h" |
#include "tgsi/tgsi_transform.h" |
#include "tgsi/tgsi_dump.h" |
#include "tgsi/tgsi_scan.h" |
/** Approx number of new tokens for instructions in pstip_transform_inst() */ |
#define NUM_NEW_TOKENS 50 |
static void |
util_pstipple_update_stipple_texture(struct pipe_context *pipe, |
struct pipe_resource *tex, |
const uint32_t pattern[32]) |
{ |
static const uint bit31 = 1 << 31; |
struct pipe_transfer *transfer; |
ubyte *data; |
int i, j; |
/* map texture memory */ |
data = pipe_transfer_map(pipe, tex, 0, 0, |
PIPE_TRANSFER_WRITE, 0, 0, 32, 32, &transfer); |
/* |
* Load alpha texture. |
* Note: 0 means keep the fragment, 255 means kill it. |
* We'll negate the texel value and use KILL_IF which kills if value |
* is negative. |
*/ |
for (i = 0; i < 32; i++) { |
for (j = 0; j < 32; j++) { |
if (pattern[i] & (bit31 >> j)) { |
/* fragment "on" */ |
data[i * transfer->stride + j] = 0; |
} |
else { |
/* fragment "off" */ |
data[i * transfer->stride + j] = 255; |
} |
} |
} |
/* unmap */ |
pipe->transfer_unmap(pipe, transfer); |
} |
/** |
* Create a 32x32 alpha8 texture that encodes the given stipple pattern. |
*/ |
struct pipe_resource * |
util_pstipple_create_stipple_texture(struct pipe_context *pipe, |
const uint32_t pattern[32]) |
{ |
struct pipe_screen *screen = pipe->screen; |
struct pipe_resource templat, *tex; |
memset(&templat, 0, sizeof(templat)); |
templat.target = PIPE_TEXTURE_2D; |
templat.format = PIPE_FORMAT_A8_UNORM; |
templat.last_level = 0; |
templat.width0 = 32; |
templat.height0 = 32; |
templat.depth0 = 1; |
templat.array_size = 1; |
templat.bind = PIPE_BIND_SAMPLER_VIEW; |
tex = screen->resource_create(screen, &templat); |
if (tex) |
util_pstipple_update_stipple_texture(pipe, tex, pattern); |
return tex; |
} |
/** |
* Create sampler view to sample the stipple texture. |
*/ |
struct pipe_sampler_view * |
util_pstipple_create_sampler_view(struct pipe_context *pipe, |
struct pipe_resource *tex) |
{ |
struct pipe_sampler_view templat, *sv; |
u_sampler_view_default_template(&templat, tex, tex->format); |
sv = pipe->create_sampler_view(pipe, tex, &templat); |
return sv; |
} |
/** |
* Create the sampler CSO that'll be used for stippling. |
*/ |
void * |
util_pstipple_create_sampler(struct pipe_context *pipe) |
{ |
struct pipe_sampler_state templat; |
void *s; |
memset(&templat, 0, sizeof(templat)); |
templat.wrap_s = PIPE_TEX_WRAP_REPEAT; |
templat.wrap_t = PIPE_TEX_WRAP_REPEAT; |
templat.wrap_r = PIPE_TEX_WRAP_REPEAT; |
templat.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; |
templat.min_img_filter = PIPE_TEX_FILTER_NEAREST; |
templat.mag_img_filter = PIPE_TEX_FILTER_NEAREST; |
templat.normalized_coords = 1; |
templat.min_lod = 0.0f; |
templat.max_lod = 0.0f; |
s = pipe->create_sampler_state(pipe, &templat); |
return s; |
} |
/** |
* Subclass of tgsi_transform_context, used for transforming the |
* user's fragment shader to add the extra texture sample and fragment kill |
* instructions. |
*/ |
struct pstip_transform_context { |
struct tgsi_transform_context base; |
struct tgsi_shader_info info; |
uint tempsUsed; /**< bitmask */ |
int wincoordInput; |
int maxInput; |
uint samplersUsed; /**< bitfield of samplers used */ |
int freeSampler; /** an available sampler for the pstipple */ |
int texTemp; /**< temp registers */ |
int numImmed; |
boolean firstInstruction; |
uint coordOrigin; |
}; |
/** |
* TGSI declaration transform callback. |
* Track samplers used, temps used, inputs used. |
*/ |
static void |
pstip_transform_decl(struct tgsi_transform_context *ctx, |
struct tgsi_full_declaration *decl) |
{ |
struct pstip_transform_context *pctx = |
(struct pstip_transform_context *) ctx; |
/* XXX we can use tgsi_shader_info instead of some of this */ |
if (decl->Declaration.File == TGSI_FILE_SAMPLER) { |
uint i; |
for (i = decl->Range.First; i <= decl->Range.Last; i++) { |
pctx->samplersUsed |= 1 << i; |
} |
} |
else if (decl->Declaration.File == TGSI_FILE_INPUT) { |
pctx->maxInput = MAX2(pctx->maxInput, (int) decl->Range.Last); |
if (decl->Semantic.Name == TGSI_SEMANTIC_POSITION) |
pctx->wincoordInput = (int) decl->Range.First; |
} |
else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) { |
uint i; |
for (i = decl->Range.First; i <= decl->Range.Last; i++) { |
pctx->tempsUsed |= (1 << i); |
} |
} |
ctx->emit_declaration(ctx, decl); |
} |
static void |
pstip_transform_immed(struct tgsi_transform_context *ctx, |
struct tgsi_full_immediate *immed) |
{ |
struct pstip_transform_context *pctx = |
(struct pstip_transform_context *) ctx; |
pctx->numImmed++; |
} |
/** |
* Find the lowest zero bit in the given word, or -1 if bitfield is all ones. |
*/ |
static int |
free_bit(uint bitfield) |
{ |
return ffs(~bitfield) - 1; |
} |
/** |
* TGSI instruction transform callback. |
* Before the first instruction, insert our new code to sample the |
* stipple texture (using the fragment coord register) then kill the |
* fragment if the stipple texture bit is off. |
* |
* Insert: |
* declare new registers |
* MUL texTemp, INPUT[wincoord], 1/32; |
* TEX texTemp, texTemp, sampler; |
* KILL_IF -texTemp; # if -texTemp < 0, kill fragment |
* [...original code...] |
*/ |
static void |
pstip_transform_inst(struct tgsi_transform_context *ctx, |
struct tgsi_full_instruction *inst) |
{ |
struct pstip_transform_context *pctx = |
(struct pstip_transform_context *) ctx; |
if (pctx->firstInstruction) { |
/* emit our new declarations before the first instruction */ |
struct tgsi_full_declaration decl; |
struct tgsi_full_instruction newInst; |
uint i; |
int wincoordInput; |
/* find free texture sampler */ |
pctx->freeSampler = free_bit(pctx->samplersUsed); |
if (pctx->freeSampler >= PIPE_MAX_SAMPLERS) |
pctx->freeSampler = PIPE_MAX_SAMPLERS - 1; |
if (pctx->wincoordInput < 0) |
wincoordInput = pctx->maxInput + 1; |
else |
wincoordInput = pctx->wincoordInput; |
/* find one free temp register */ |
for (i = 0; i < 32; i++) { |
if ((pctx->tempsUsed & (1 << i)) == 0) { |
/* found a free temp */ |
if (pctx->texTemp < 0) |
pctx->texTemp = i; |
else |
break; |
} |
} |
assert(pctx->texTemp >= 0); |
if (pctx->wincoordInput < 0) { |
/* declare new position input reg */ |
decl = tgsi_default_full_declaration(); |
decl.Declaration.File = TGSI_FILE_INPUT; |
decl.Declaration.Interpolate = 1; |
decl.Declaration.Semantic = 1; |
decl.Semantic.Name = TGSI_SEMANTIC_POSITION; |
decl.Semantic.Index = 0; |
decl.Range.First = |
decl.Range.Last = wincoordInput; |
decl.Interp.Interpolate = TGSI_INTERPOLATE_LINEAR; |
ctx->emit_declaration(ctx, &decl); |
} |
/* declare new sampler */ |
decl = tgsi_default_full_declaration(); |
decl.Declaration.File = TGSI_FILE_SAMPLER; |
decl.Range.First = |
decl.Range.Last = pctx->freeSampler; |
ctx->emit_declaration(ctx, &decl); |
/* declare new temp regs */ |
decl = tgsi_default_full_declaration(); |
decl.Declaration.File = TGSI_FILE_TEMPORARY; |
decl.Range.First = |
decl.Range.Last = pctx->texTemp; |
ctx->emit_declaration(ctx, &decl); |
/* emit immediate = {1/32, 1/32, 1, 1} |
* The index/position of this immediate will be pctx->numImmed |
*/ |
{ |
static const float value[4] = { 1.0/32, 1.0/32, 1.0, 1.0 }; |
struct tgsi_full_immediate immed; |
uint size = 4; |
immed = tgsi_default_full_immediate(); |
immed.Immediate.NrTokens = 1 + size; /* one for the token itself */ |
immed.u[0].Float = value[0]; |
immed.u[1].Float = value[1]; |
immed.u[2].Float = value[2]; |
immed.u[3].Float = value[3]; |
ctx->emit_immediate(ctx, &immed); |
} |
pctx->firstInstruction = FALSE; |
/* |
* Insert new MUL/TEX/KILL_IF instructions at start of program |
* Take gl_FragCoord, divide by 32 (stipple size), sample the |
* texture and kill fragment if needed. |
* |
* We'd like to use non-normalized texcoords to index into a RECT |
* texture, but we can only use REPEAT wrap mode with normalized |
* texcoords. Darn. |
*/ |
/* XXX invert wincoord if origin isn't lower-left... */ |
/* MUL texTemp, INPUT[wincoord], 1/32; */ |
newInst = tgsi_default_full_instruction(); |
newInst.Instruction.Opcode = TGSI_OPCODE_MUL; |
newInst.Instruction.NumDstRegs = 1; |
newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY; |
newInst.Dst[0].Register.Index = pctx->texTemp; |
newInst.Instruction.NumSrcRegs = 2; |
newInst.Src[0].Register.File = TGSI_FILE_INPUT; |
newInst.Src[0].Register.Index = wincoordInput; |
newInst.Src[1].Register.File = TGSI_FILE_IMMEDIATE; |
newInst.Src[1].Register.Index = pctx->numImmed; |
ctx->emit_instruction(ctx, &newInst); |
/* TEX texTemp, texTemp, sampler; */ |
newInst = tgsi_default_full_instruction(); |
newInst.Instruction.Opcode = TGSI_OPCODE_TEX; |
newInst.Instruction.NumDstRegs = 1; |
newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY; |
newInst.Dst[0].Register.Index = pctx->texTemp; |
newInst.Instruction.NumSrcRegs = 2; |
newInst.Instruction.Texture = TRUE; |
newInst.Texture.Texture = TGSI_TEXTURE_2D; |
newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY; |
newInst.Src[0].Register.Index = pctx->texTemp; |
newInst.Src[1].Register.File = TGSI_FILE_SAMPLER; |
newInst.Src[1].Register.Index = pctx->freeSampler; |
ctx->emit_instruction(ctx, &newInst); |
/* KILL_IF -texTemp; # if -texTemp < 0, kill fragment */ |
newInst = tgsi_default_full_instruction(); |
newInst.Instruction.Opcode = TGSI_OPCODE_KILL_IF; |
newInst.Instruction.NumDstRegs = 0; |
newInst.Instruction.NumSrcRegs = 1; |
newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY; |
newInst.Src[0].Register.Index = pctx->texTemp; |
newInst.Src[0].Register.Negate = 1; |
ctx->emit_instruction(ctx, &newInst); |
} |
/* emit this instruction */ |
ctx->emit_instruction(ctx, inst); |
} |
/** |
* Given a fragment shader, return a new fragment shader which |
* samples a stipple texture and executes KILL. |
*/ |
struct pipe_shader_state * |
util_pstipple_create_fragment_shader(struct pipe_context *pipe, |
struct pipe_shader_state *fs, |
unsigned *samplerUnitOut) |
{ |
struct pipe_shader_state *new_fs; |
struct pstip_transform_context transform; |
const uint newLen = tgsi_num_tokens(fs->tokens) + NUM_NEW_TOKENS; |
unsigned i; |
new_fs = MALLOC(sizeof(*new_fs)); |
if (!new_fs) |
return NULL; |
new_fs->tokens = tgsi_alloc_tokens(newLen); |
if (!new_fs->tokens) { |
FREE(new_fs); |
return NULL; |
} |
/* Setup shader transformation info/context. |
*/ |
memset(&transform, 0, sizeof(transform)); |
transform.wincoordInput = -1; |
transform.maxInput = -1; |
transform.texTemp = -1; |
transform.firstInstruction = TRUE; |
transform.coordOrigin = TGSI_FS_COORD_ORIGIN_UPPER_LEFT; |
transform.base.transform_instruction = pstip_transform_inst; |
transform.base.transform_declaration = pstip_transform_decl; |
transform.base.transform_immediate = pstip_transform_immed; |
tgsi_scan_shader(fs->tokens, &transform.info); |
/* find fragment coordinate origin property */ |
for (i = 0; i < transform.info.num_properties; i++) { |
if (transform.info.properties[i].name == TGSI_PROPERTY_FS_COORD_ORIGIN) |
transform.coordOrigin = transform.info.properties[i].data[0]; |
} |
tgsi_transform_shader(fs->tokens, |
(struct tgsi_token *) new_fs->tokens, |
newLen, &transform.base); |
#if 0 /* DEBUG */ |
tgsi_dump(fs->tokens, 0); |
tgsi_dump(new_fs->tokens, 0); |
#endif |
assert(transform.freeSampler < PIPE_MAX_SAMPLERS); |
*samplerUnitOut = transform.freeSampler; |
return new_fs; |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_pstipple.h |
---|
0,0 → 1,56 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* Copyright 2010 VMware, Inc. |
* 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 TUNGSTEN GRAPHICS 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_PSTIPPLE_H |
#define U_PSTIPPLE_H |
#include "pipe/p_compiler.h" |
struct pipe_context; |
struct pipe_resource; |
struct pipe_shader_state; |
extern struct pipe_resource * |
util_pstipple_create_stipple_texture(struct pipe_context *pipe, |
const uint32_t pattern[32]); |
extern struct pipe_sampler_view * |
util_pstipple_create_sampler_view(struct pipe_context *pipe, |
struct pipe_resource *tex); |
extern void * |
util_pstipple_create_sampler(struct pipe_context *pipe); |
extern struct pipe_shader_state * |
util_pstipple_create_fragment_shader(struct pipe_context *pipe, |
struct pipe_shader_state *fs, |
unsigned *samplerUnitOut); |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_range.h |
---|
0,0 → 1,89 |
/* |
* Copyright 2013 Marek Olšák <maraeo@gmail.com> |
* |
* 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 |
* on 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 |
* THE AUTHOR(S) AND/OR THEIR 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. */ |
/** |
* @file |
* 1D integer range, capable of the union and intersection operations. |
* |
* It only maintains a single interval which is extended when the union is |
* done. This implementation is partially thread-safe (readers are not |
* protected by a lock). |
* |
* @author Marek Olšák |
*/ |
#ifndef U_RANGE_H |
#define U_RANGE_H |
#include "os/os_thread.h" |
struct util_range { |
unsigned start; /* inclusive */ |
unsigned end; /* exclusive */ |
/* for the range to be consistent with multiple contexts: */ |
pipe_mutex write_mutex; |
}; |
static INLINE void |
util_range_set_empty(struct util_range *range) |
{ |
range->start = ~0; |
range->end = 0; |
} |
/* This is like a union of two sets. */ |
static INLINE void |
util_range_add(struct util_range *range, unsigned start, unsigned end) |
{ |
if (start < range->start || end > range->end) { |
pipe_mutex_lock(range->write_mutex); |
range->start = MIN2(start, range->start); |
range->end = MAX2(end, range->end); |
pipe_mutex_unlock(range->write_mutex); |
} |
} |
static INLINE boolean |
util_ranges_intersect(struct util_range *range, unsigned start, unsigned end) |
{ |
return MAX2(start, range->start) < MIN2(end, range->end); |
} |
/* Init/deinit */ |
static INLINE void |
util_range_init(struct util_range *range) |
{ |
pipe_mutex_init(range->write_mutex); |
util_range_set_empty(range); |
} |
static INLINE void |
util_range_destroy(struct util_range *range) |
{ |
pipe_mutex_destroy(range->write_mutex); |
} |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_rect.h |
---|
0,0 → 1,92 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* 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 TUNGSTEN GRAPHICS 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_RECT_H |
#define U_RECT_H |
#include "pipe/p_compiler.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
struct u_rect { |
int x0, x1; |
int y0, y1; |
}; |
/* Do two rectangles intersect? |
*/ |
static INLINE boolean |
u_rect_test_intersection(const struct u_rect *a, |
const struct u_rect *b) |
{ |
return (!(a->x1 < b->x0 || |
b->x1 < a->x0 || |
a->y1 < b->y0 || |
b->y1 < a->y0)); |
} |
/* Find the intersection of two rectangles known to intersect. |
*/ |
static INLINE void |
u_rect_find_intersection(const struct u_rect *a, |
struct u_rect *b) |
{ |
/* Caller should verify intersection exists before calling. |
*/ |
if (b->x0 < a->x0) b->x0 = a->x0; |
if (b->x1 > a->x1) b->x1 = a->x1; |
if (b->y0 < a->y0) b->y0 = a->y0; |
if (b->y1 > a->y1) b->y1 = a->y1; |
} |
static INLINE void |
u_rect_possible_intersection(const struct u_rect *a, |
struct u_rect *b) |
{ |
if (u_rect_test_intersection(a,b)) { |
u_rect_find_intersection(a,b); |
} |
else { |
b->x0 = b->x1 = b->y0 = b->y1 = 0; |
} |
} |
#ifdef __cplusplus |
} |
#endif |
/* Include pipe copy/fill rect helpers declarations for backwards compatibility |
*/ |
#include "util/u_surface.h" |
#endif /* U_RECT_H */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_resource.c |
---|
0,0 → 1,65 |
/* |
* Copyright 2013 VMware, Inc. |
* 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 THE 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 "pipe/p_defines.h" |
#include "pipe/p_state.h" |
#include "util/u_format.h" |
#include "util/u_math.h" |
#include "util/u_resource.h" |
/** |
* Return the size of the resource in bytes. |
*/ |
unsigned |
util_resource_size(const struct pipe_resource *res) |
{ |
unsigned width = res->width0; |
unsigned height = res->height0; |
unsigned depth = res->depth0; |
unsigned size = 0; |
unsigned level; |
for (level = 0; level <= res->last_level; level++) { |
unsigned slices; |
if (res->target == PIPE_TEXTURE_CUBE) |
slices = 6; |
else if (res->target == PIPE_TEXTURE_3D) |
slices = depth; |
else |
slices = res->array_size; |
size += (util_format_get_nblocksy(res->format, height) * |
util_format_get_stride(res->format, width) * slices); |
width = u_minify(width, 1); |
height = u_minify(height, 1); |
depth = u_minify(depth, 1); |
} |
return size; |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_resource.h |
---|
0,0 → 1,52 |
/* |
* Copyright 2013 VMware, Inc. |
* 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 THE 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_RESOURCE_H |
#define U_RESOURCE_H |
#include "pipe/p_state.h" |
unsigned |
util_resource_size(const struct pipe_resource *res); |
/** |
* Return true if the resource is an array texture. |
* |
* Note that this function returns true for single-layered array textures. |
*/ |
static INLINE boolean |
util_resource_is_array_texture(const struct pipe_resource *res) |
{ |
switch (res->target) { |
case PIPE_TEXTURE_1D_ARRAY: |
case PIPE_TEXTURE_2D_ARRAY: |
case PIPE_TEXTURE_CUBE_ARRAY: |
return TRUE; |
default: |
return FALSE; |
} |
} |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_ringbuffer.c |
---|
0,0 → 1,160 |
#include "os/os_thread.h" |
#include "pipe/p_defines.h" |
#include "util/u_ringbuffer.h" |
#include "util/u_math.h" |
#include "util/u_memory.h" |
/* Generic ringbuffer: |
*/ |
struct util_ringbuffer |
{ |
struct util_packet *buf; |
unsigned mask; |
/* Can this be done with atomic variables?? |
*/ |
unsigned head; |
unsigned tail; |
pipe_condvar change; |
pipe_mutex mutex; |
}; |
struct util_ringbuffer *util_ringbuffer_create( unsigned dwords ) |
{ |
struct util_ringbuffer *ring = CALLOC_STRUCT(util_ringbuffer); |
if (ring == NULL) |
return NULL; |
assert(util_is_power_of_two(dwords)); |
ring->buf = MALLOC( dwords * sizeof(unsigned) ); |
if (ring->buf == NULL) |
goto fail; |
ring->mask = dwords - 1; |
pipe_condvar_init(ring->change); |
pipe_mutex_init(ring->mutex); |
return ring; |
fail: |
FREE(ring->buf); |
FREE(ring); |
return NULL; |
} |
void util_ringbuffer_destroy( struct util_ringbuffer *ring ) |
{ |
pipe_condvar_destroy(ring->change); |
pipe_mutex_destroy(ring->mutex); |
FREE(ring->buf); |
FREE(ring); |
} |
/** |
* Return number of free entries in the ring |
*/ |
static INLINE unsigned util_ringbuffer_space( const struct util_ringbuffer *ring ) |
{ |
return (ring->tail - (ring->head + 1)) & ring->mask; |
} |
/** |
* Is the ring buffer empty? |
*/ |
static INLINE boolean util_ringbuffer_empty( const struct util_ringbuffer *ring ) |
{ |
return util_ringbuffer_space(ring) == ring->mask; |
} |
void util_ringbuffer_enqueue( struct util_ringbuffer *ring, |
const struct util_packet *packet ) |
{ |
unsigned i; |
/* XXX: over-reliance on mutexes, etc: |
*/ |
pipe_mutex_lock(ring->mutex); |
/* make sure we don't request an impossible amount of space |
*/ |
assert(packet->dwords <= ring->mask); |
/* Wait for free space: |
*/ |
while (util_ringbuffer_space(ring) < packet->dwords) |
pipe_condvar_wait(ring->change, ring->mutex); |
/* Copy data to ring: |
*/ |
for (i = 0; i < packet->dwords; i++) { |
/* Copy all dwords of the packet. Note we're abusing the |
* typesystem a little - we're being passed a pointer to |
* something, but probably not an array of packet structs: |
*/ |
ring->buf[ring->head] = packet[i]; |
ring->head++; |
ring->head &= ring->mask; |
} |
/* Signal change: |
*/ |
pipe_condvar_signal(ring->change); |
pipe_mutex_unlock(ring->mutex); |
} |
enum pipe_error util_ringbuffer_dequeue( struct util_ringbuffer *ring, |
struct util_packet *packet, |
unsigned max_dwords, |
boolean wait ) |
{ |
const struct util_packet *ring_packet; |
unsigned i; |
int ret = PIPE_OK; |
/* XXX: over-reliance on mutexes, etc: |
*/ |
pipe_mutex_lock(ring->mutex); |
/* Get next ring entry: |
*/ |
if (wait) { |
while (util_ringbuffer_empty(ring)) |
pipe_condvar_wait(ring->change, ring->mutex); |
} |
else { |
if (util_ringbuffer_empty(ring)) { |
ret = PIPE_ERROR_OUT_OF_MEMORY; |
goto out; |
} |
} |
ring_packet = &ring->buf[ring->tail]; |
/* Both of these are considered bugs. Raise an assert on debug builds. |
*/ |
if (ring_packet->dwords > ring->mask + 1 - util_ringbuffer_space(ring) || |
ring_packet->dwords > max_dwords) { |
assert(0); |
ret = PIPE_ERROR_BAD_INPUT; |
goto out; |
} |
/* Copy data from ring: |
*/ |
for (i = 0; i < ring_packet->dwords; i++) { |
packet[i] = ring->buf[ring->tail]; |
ring->tail++; |
ring->tail &= ring->mask; |
} |
out: |
/* Signal change: |
*/ |
pipe_condvar_signal(ring->change); |
pipe_mutex_unlock(ring->mutex); |
return ret; |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_ringbuffer.h |
---|
0,0 → 1,29 |
#ifndef UTIL_RINGBUFFER_H |
#define UTIL_RINGBUFFER_H |
#include "pipe/p_compiler.h" |
#include "pipe/p_defines.h" /* only for pipe_error! */ |
/* Generic header |
*/ |
struct util_packet { |
unsigned dwords:8; |
unsigned data24:24; |
}; |
struct util_ringbuffer; |
struct util_ringbuffer *util_ringbuffer_create( unsigned dwords ); |
void util_ringbuffer_destroy( struct util_ringbuffer *ring ); |
void util_ringbuffer_enqueue( struct util_ringbuffer *ring, |
const struct util_packet *packet ); |
enum pipe_error util_ringbuffer_dequeue( struct util_ringbuffer *ring, |
struct util_packet *packet, |
unsigned max_dwords, |
boolean wait ); |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_sampler.c |
---|
0,0 → 1,109 |
/************************************************************************** |
* |
* Copyright 2010 VMware, Inc. |
* 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 VMWARE 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 "u_format.h" |
#include "u_sampler.h" |
/** |
* Initialize a pipe_sampler_view. 'view' is considered to have |
* uninitialized contents. |
*/ |
static void |
default_template(struct pipe_sampler_view *view, |
const struct pipe_resource *texture, |
enum pipe_format format, |
unsigned expand_green_blue) |
{ |
memset(view, 0, sizeof(*view)); |
/* XXX: Check if format is compatible with texture->format. |
*/ |
view->format = format; |
view->u.tex.first_level = 0; |
view->u.tex.last_level = texture->last_level; |
view->u.tex.first_layer = 0; |
view->u.tex.last_layer = texture->target == PIPE_TEXTURE_3D ? |
texture->depth0 - 1 : texture->array_size - 1; |
view->swizzle_r = PIPE_SWIZZLE_RED; |
view->swizzle_g = PIPE_SWIZZLE_GREEN; |
view->swizzle_b = PIPE_SWIZZLE_BLUE; |
view->swizzle_a = PIPE_SWIZZLE_ALPHA; |
/* Override default green and blue component expansion to the requested |
* one. |
* |
* Gallium expands nonexistent components to (0,0,0,1), DX9 expands |
* to (1,1,1,1). Since alpha is always expanded to 1, and red is |
* always present, we only really care about green and blue |
* components. |
* |
* To make it look less hackish, one would have to add |
* UTIL_FORMAT_SWIZZLE_EXPAND to indicate components for expansion |
* and then override without exceptions or favoring one component |
* over another. |
*/ |
if (format != PIPE_FORMAT_A8_UNORM) { |
const struct util_format_description *desc = util_format_description(format); |
assert(desc); |
if (desc) { |
if (desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_0) { |
view->swizzle_g = expand_green_blue; |
} |
if (desc->swizzle[2] == UTIL_FORMAT_SWIZZLE_0) { |
view->swizzle_b = expand_green_blue; |
} |
} |
} |
} |
void |
u_sampler_view_default_template(struct pipe_sampler_view *view, |
const struct pipe_resource *texture, |
enum pipe_format format) |
{ |
/* Expand to (0, 0, 0, 1) */ |
default_template(view, |
texture, |
format, |
PIPE_SWIZZLE_ZERO); |
} |
void |
u_sampler_view_default_dx9_template(struct pipe_sampler_view *view, |
const struct pipe_resource *texture, |
enum pipe_format format) |
{ |
/* Expand to (1, 1, 1, 1) */ |
default_template(view, |
texture, |
format, |
PIPE_SWIZZLE_ONE); |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_sampler.h |
---|
0,0 → 1,57 |
/************************************************************************** |
* |
* Copyright 2010 VMware, Inc. |
* 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 VMWARE 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_SAMPLER_H |
#define U_SAMPLER_H |
#include "pipe/p_defines.h" |
#include "pipe/p_format.h" |
#include "pipe/p_state.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
void |
u_sampler_view_default_template(struct pipe_sampler_view *view, |
const struct pipe_resource *texture, |
enum pipe_format format); |
void |
u_sampler_view_default_dx9_template(struct pipe_sampler_view *view, |
const struct pipe_resource *texture, |
enum pipe_format format); |
#ifdef __cplusplus |
} /* extern "C" { */ |
#endif |
#endif /* U_SAMPLER_H */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_simple_list.h |
---|
0,0 → 1,199 |
/** |
* \file simple_list.h |
* Simple macros for type-safe, intrusive lists. |
* |
* Intended to work with a list sentinal which is created as an empty |
* list. Insert & delete are O(1). |
* |
* \author |
* (C) 1997, Keith Whitwell |
*/ |
/* |
* Mesa 3-D graphics library |
* |
* Copyright (C) 1999-2001 Brian Paul 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, sublicense, |
* 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 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 NONINFRINGEMENT. IN NO EVENT SHALL |
* THE AUTHORS OR COPYRIGHT HOLDERS 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_SIMPLE_LIST_H_ |
#define _U_SIMPLE_LIST_H_ |
/** |
* Remove an element from list. |
* |
* \param elem element to remove. |
*/ |
#define remove_from_list(elem) \ |
do { \ |
(elem)->next->prev = (elem)->prev; \ |
(elem)->prev->next = (elem)->next; \ |
(elem)->next = elem; \ |
(elem)->prev = elem; \ |
} while (0) |
/** |
* Insert an element to the list head. |
* |
* \param list list. |
* \param elem element to insert. |
*/ |
#define insert_at_head(list, elem) \ |
do { \ |
(elem)->prev = list; \ |
(elem)->next = (list)->next; \ |
(list)->next->prev = elem; \ |
(list)->next = elem; \ |
} while(0) |
/** |
* Insert an element to the list tail. |
* |
* \param list list. |
* \param elem element to insert. |
*/ |
#define insert_at_tail(list, elem) \ |
do { \ |
(elem)->next = list; \ |
(elem)->prev = (list)->prev; \ |
(list)->prev->next = elem; \ |
(list)->prev = elem; \ |
} while(0) |
/** |
* Move an element to the list head. |
* |
* \param list list. |
* \param elem element to move. |
*/ |
#define move_to_head(list, elem) \ |
do { \ |
remove_from_list(elem); \ |
insert_at_head(list, elem); \ |
} while (0) |
/** |
* Move an element to the list tail. |
* |
* \param list list. |
* \param elem element to move. |
*/ |
#define move_to_tail(list, elem) \ |
do { \ |
remove_from_list(elem); \ |
insert_at_tail(list, elem); \ |
} while (0) |
/** |
* Make a empty list empty. |
* |
* \param sentinal list (sentinal element). |
*/ |
#define make_empty_list(sentinal) \ |
do { \ |
(sentinal)->next = sentinal; \ |
(sentinal)->prev = sentinal; \ |
} while (0) |
/** |
* Get list first element. |
* |
* \param list list. |
* |
* \return pointer to first element. |
*/ |
#define first_elem(list) ((list)->next) |
/** |
* Get list last element. |
* |
* \param list list. |
* |
* \return pointer to last element. |
*/ |
#define last_elem(list) ((list)->prev) |
/** |
* Get next element. |
* |
* \param elem element. |
* |
* \return pointer to next element. |
*/ |
#define next_elem(elem) ((elem)->next) |
/** |
* Get previous element. |
* |
* \param elem element. |
* |
* \return pointer to previous element. |
*/ |
#define prev_elem(elem) ((elem)->prev) |
/** |
* Test whether element is at end of the list. |
* |
* \param list list. |
* \param elem element. |
* |
* \return non-zero if element is at end of list, or zero otherwise. |
*/ |
#define at_end(list, elem) ((elem) == (list)) |
/** |
* Test if a list is empty. |
* |
* \param list list. |
* |
* \return non-zero if list empty, or zero otherwise. |
*/ |
#define is_empty_list(list) ((list)->next == (list)) |
/** |
* Walk through the elements of a list. |
* |
* \param ptr pointer to the current element. |
* \param list list. |
* |
* \note It should be followed by a { } block or a single statement, as in a \c |
* for loop. |
*/ |
#define foreach(ptr, list) \ |
for( ptr=(list)->next ; ptr!=list ; ptr=(ptr)->next ) |
/** |
* Walk through the elements of a list. |
* |
* Same as #foreach but lets you unlink the current value during a list |
* traversal. Useful for freeing a list, element by element. |
* |
* \param ptr pointer to the current element. |
* \param t temporary pointer. |
* \param list list. |
* |
* \note It should be followed by a { } block or a single statement, as in a \c |
* for loop. |
*/ |
#define foreach_s(ptr, t, list) \ |
for(ptr=(list)->next,t=(ptr)->next; list != ptr; ptr=t, t=(t)->next) |
#endif /* _U_SIMPLE_LIST_H_ */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_simple_shaders.c |
---|
0,0 → 1,529 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* All Rights Reserved. |
* Copyright 2009 Marek Olšák <maraeo@gmail.com> |
* |
* 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 TUNGSTEN GRAPHICS 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. |
* |
**************************************************************************/ |
/** |
* @file |
* Simple vertex/fragment shader generators. |
* |
* @author Brian Paul |
Marek Olšák |
*/ |
#include "pipe/p_context.h" |
#include "pipe/p_shader_tokens.h" |
#include "pipe/p_state.h" |
#include "util/u_simple_shaders.h" |
#include "util/u_debug.h" |
#include "util/u_memory.h" |
#include "tgsi/tgsi_dump.h" |
#include "tgsi/tgsi_strings.h" |
#include "tgsi/tgsi_ureg.h" |
#include "tgsi/tgsi_text.h" |
#include <stdio.h> /* include last */ |
/** |
* Make simple vertex pass-through shader. |
* \param num_attribs number of attributes to pass through |
* \param semantic_names array of semantic names for each attribute |
* \param semantic_indexes array of semantic indexes for each attribute |
*/ |
void * |
util_make_vertex_passthrough_shader(struct pipe_context *pipe, |
uint num_attribs, |
const uint *semantic_names, |
const uint *semantic_indexes) |
{ |
return util_make_vertex_passthrough_shader_with_so(pipe, num_attribs, |
semantic_names, |
semantic_indexes, NULL); |
} |
void * |
util_make_vertex_passthrough_shader_with_so(struct pipe_context *pipe, |
uint num_attribs, |
const uint *semantic_names, |
const uint *semantic_indexes, |
const struct pipe_stream_output_info *so) |
{ |
struct ureg_program *ureg; |
uint i; |
ureg = ureg_create( TGSI_PROCESSOR_VERTEX ); |
if (ureg == NULL) |
return NULL; |
for (i = 0; i < num_attribs; i++) { |
struct ureg_src src; |
struct ureg_dst dst; |
src = ureg_DECL_vs_input( ureg, i ); |
dst = ureg_DECL_output( ureg, |
semantic_names[i], |
semantic_indexes[i]); |
ureg_MOV( ureg, dst, src ); |
} |
ureg_END( ureg ); |
return ureg_create_shader_with_so_and_destroy( ureg, pipe, so ); |
} |
/** |
* Make simple fragment texture shader: |
* IMM {0,0,0,1} // (if writemask != 0xf) |
* MOV OUT[0], IMM[0] // (if writemask != 0xf) |
* TEX OUT[0].writemask, IN[0], SAMP[0], 2D; |
* END; |
* |
* \param tex_target one of PIPE_TEXTURE_x |
* \parma interp_mode either TGSI_INTERPOLATE_LINEAR or PERSPECTIVE |
* \param writemask mask of TGSI_WRITEMASK_x |
*/ |
void * |
util_make_fragment_tex_shader_writemask(struct pipe_context *pipe, |
unsigned tex_target, |
unsigned interp_mode, |
unsigned writemask ) |
{ |
struct ureg_program *ureg; |
struct ureg_src sampler; |
struct ureg_src tex; |
struct ureg_dst out; |
assert(interp_mode == TGSI_INTERPOLATE_LINEAR || |
interp_mode == TGSI_INTERPOLATE_PERSPECTIVE); |
ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT ); |
if (ureg == NULL) |
return NULL; |
sampler = ureg_DECL_sampler( ureg, 0 ); |
tex = ureg_DECL_fs_input( ureg, |
TGSI_SEMANTIC_GENERIC, 0, |
interp_mode ); |
out = ureg_DECL_output( ureg, |
TGSI_SEMANTIC_COLOR, |
0 ); |
if (writemask != TGSI_WRITEMASK_XYZW) { |
struct ureg_src imm = ureg_imm4f( ureg, 0, 0, 0, 1 ); |
ureg_MOV( ureg, out, imm ); |
} |
ureg_TEX( ureg, |
ureg_writemask(out, writemask), |
tex_target, tex, sampler ); |
ureg_END( ureg ); |
return ureg_create_shader_and_destroy( ureg, pipe ); |
} |
/** |
* Make a simple fragment shader that sets the output color to a color |
* taken from a texture. |
* \param tex_target one of PIPE_TEXTURE_x |
*/ |
void * |
util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target, |
unsigned interp_mode) |
{ |
return util_make_fragment_tex_shader_writemask( pipe, |
tex_target, |
interp_mode, |
TGSI_WRITEMASK_XYZW ); |
} |
/** |
* Make a simple fragment texture shader which reads an X component from |
* a texture and writes it as depth. |
*/ |
void * |
util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe, |
unsigned tex_target, |
unsigned interp_mode) |
{ |
struct ureg_program *ureg; |
struct ureg_src sampler; |
struct ureg_src tex; |
struct ureg_dst out, depth; |
struct ureg_src imm; |
ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT ); |
if (ureg == NULL) |
return NULL; |
sampler = ureg_DECL_sampler( ureg, 0 ); |
tex = ureg_DECL_fs_input( ureg, |
TGSI_SEMANTIC_GENERIC, 0, |
interp_mode ); |
out = ureg_DECL_output( ureg, |
TGSI_SEMANTIC_COLOR, |
0 ); |
depth = ureg_DECL_output( ureg, |
TGSI_SEMANTIC_POSITION, |
0 ); |
imm = ureg_imm4f( ureg, 0, 0, 0, 1 ); |
ureg_MOV( ureg, out, imm ); |
ureg_TEX( ureg, |
ureg_writemask(depth, TGSI_WRITEMASK_Z), |
tex_target, tex, sampler ); |
ureg_END( ureg ); |
return ureg_create_shader_and_destroy( ureg, pipe ); |
} |
/** |
* Make a simple fragment texture shader which reads the texture unit 0 and 1 |
* and writes it as depth and stencil, respectively. |
*/ |
void * |
util_make_fragment_tex_shader_writedepthstencil(struct pipe_context *pipe, |
unsigned tex_target, |
unsigned interp_mode) |
{ |
struct ureg_program *ureg; |
struct ureg_src depth_sampler, stencil_sampler; |
struct ureg_src tex; |
struct ureg_dst out, depth, stencil; |
struct ureg_src imm; |
ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT ); |
if (ureg == NULL) |
return NULL; |
depth_sampler = ureg_DECL_sampler( ureg, 0 ); |
stencil_sampler = ureg_DECL_sampler( ureg, 1 ); |
tex = ureg_DECL_fs_input( ureg, |
TGSI_SEMANTIC_GENERIC, 0, |
interp_mode ); |
out = ureg_DECL_output( ureg, |
TGSI_SEMANTIC_COLOR, |
0 ); |
depth = ureg_DECL_output( ureg, |
TGSI_SEMANTIC_POSITION, |
0 ); |
stencil = ureg_DECL_output( ureg, |
TGSI_SEMANTIC_STENCIL, |
0 ); |
imm = ureg_imm4f( ureg, 0, 0, 0, 1 ); |
ureg_MOV( ureg, out, imm ); |
ureg_TEX( ureg, |
ureg_writemask(depth, TGSI_WRITEMASK_Z), |
tex_target, tex, depth_sampler ); |
ureg_TEX( ureg, |
ureg_writemask(stencil, TGSI_WRITEMASK_Y), |
tex_target, tex, stencil_sampler ); |
ureg_END( ureg ); |
return ureg_create_shader_and_destroy( ureg, pipe ); |
} |
/** |
* Make a simple fragment texture shader which reads a texture and writes it |
* as stencil. |
*/ |
void * |
util_make_fragment_tex_shader_writestencil(struct pipe_context *pipe, |
unsigned tex_target, |
unsigned interp_mode) |
{ |
struct ureg_program *ureg; |
struct ureg_src stencil_sampler; |
struct ureg_src tex; |
struct ureg_dst out, stencil; |
struct ureg_src imm; |
ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT ); |
if (ureg == NULL) |
return NULL; |
stencil_sampler = ureg_DECL_sampler( ureg, 0 ); |
tex = ureg_DECL_fs_input( ureg, |
TGSI_SEMANTIC_GENERIC, 0, |
interp_mode ); |
out = ureg_DECL_output( ureg, |
TGSI_SEMANTIC_COLOR, |
0 ); |
stencil = ureg_DECL_output( ureg, |
TGSI_SEMANTIC_STENCIL, |
0 ); |
imm = ureg_imm4f( ureg, 0, 0, 0, 1 ); |
ureg_MOV( ureg, out, imm ); |
ureg_TEX( ureg, |
ureg_writemask(stencil, TGSI_WRITEMASK_Y), |
tex_target, tex, stencil_sampler ); |
ureg_END( ureg ); |
return ureg_create_shader_and_destroy( ureg, pipe ); |
} |
/** |
* Make simple fragment color pass-through shader that replicates OUT[0] |
* to all bound colorbuffers. |
*/ |
void * |
util_make_fragment_passthrough_shader(struct pipe_context *pipe, |
int input_semantic, |
int input_interpolate, |
boolean write_all_cbufs) |
{ |
static const char shader_templ[] = |
"FRAG\n" |
"%s" |
"DCL IN[0], %s[0], %s\n" |
"DCL OUT[0], COLOR[0]\n" |
"MOV OUT[0], IN[0]\n" |
"END\n"; |
char text[sizeof(shader_templ)+100]; |
struct tgsi_token tokens[1000]; |
struct pipe_shader_state state = {tokens}; |
sprintf(text, shader_templ, |
write_all_cbufs ? "PROPERTY FS_COLOR0_WRITES_ALL_CBUFS 1\n" : "", |
tgsi_semantic_names[input_semantic], |
tgsi_interpolate_names[input_interpolate]); |
if (!tgsi_text_translate(text, tokens, Elements(tokens))) { |
assert(0); |
return NULL; |
} |
#if 0 |
tgsi_dump(state.tokens, 0); |
#endif |
return pipe->create_fs_state(pipe, &state); |
} |
void * |
util_make_empty_fragment_shader(struct pipe_context *pipe) |
{ |
struct ureg_program *ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT); |
if (ureg == NULL) |
return NULL; |
ureg_END(ureg); |
return ureg_create_shader_and_destroy(ureg, pipe); |
} |
/** |
* Make a fragment shader that copies the input color to N output colors. |
*/ |
void * |
util_make_fragment_cloneinput_shader(struct pipe_context *pipe, int num_cbufs, |
int input_semantic, |
int input_interpolate) |
{ |
struct ureg_program *ureg; |
struct ureg_src src; |
struct ureg_dst dst[PIPE_MAX_COLOR_BUFS]; |
int i; |
assert(num_cbufs <= PIPE_MAX_COLOR_BUFS); |
ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT ); |
if (ureg == NULL) |
return NULL; |
src = ureg_DECL_fs_input( ureg, input_semantic, 0, |
input_interpolate ); |
for (i = 0; i < num_cbufs; i++) |
dst[i] = ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, i ); |
for (i = 0; i < num_cbufs; i++) |
ureg_MOV( ureg, dst[i], src ); |
ureg_END( ureg ); |
return ureg_create_shader_and_destroy( ureg, pipe ); |
} |
static void * |
util_make_fs_blit_msaa_gen(struct pipe_context *pipe, |
unsigned tgsi_tex, |
const char *output_semantic, |
const char *output_mask) |
{ |
static const char shader_templ[] = |
"FRAG\n" |
"DCL IN[0], GENERIC[0], LINEAR\n" |
"DCL SAMP[0]\n" |
"DCL OUT[0], %s\n" |
"DCL TEMP[0]\n" |
"F2U TEMP[0], IN[0]\n" |
"TXF OUT[0]%s, TEMP[0], SAMP[0], %s\n" |
"END\n"; |
const char *type = tgsi_texture_names[tgsi_tex]; |
char text[sizeof(shader_templ)+100]; |
struct tgsi_token tokens[1000]; |
struct pipe_shader_state state = {tokens}; |
assert(tgsi_tex == TGSI_TEXTURE_2D_MSAA || |
tgsi_tex == TGSI_TEXTURE_2D_ARRAY_MSAA); |
sprintf(text, shader_templ, output_semantic, output_mask, type); |
if (!tgsi_text_translate(text, tokens, Elements(tokens))) { |
puts(text); |
assert(0); |
return NULL; |
} |
#if 0 |
tgsi_dump(state.tokens, 0); |
#endif |
return pipe->create_fs_state(pipe, &state); |
} |
/** |
* Make a fragment shader that sets the output color to a color |
* fetched from a multisample texture. |
* \param tex_target one of PIPE_TEXTURE_x |
*/ |
void * |
util_make_fs_blit_msaa_color(struct pipe_context *pipe, |
unsigned tgsi_tex) |
{ |
return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, |
"COLOR[0]", ""); |
} |
/** |
* Make a fragment shader that sets the output depth to a depth value |
* fetched from a multisample texture. |
* \param tex_target one of PIPE_TEXTURE_x |
*/ |
void * |
util_make_fs_blit_msaa_depth(struct pipe_context *pipe, |
unsigned tgsi_tex) |
{ |
return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, |
"POSITION", ".z"); |
} |
/** |
* Make a fragment shader that sets the output stencil to a stencil value |
* fetched from a multisample texture. |
* \param tex_target one of PIPE_TEXTURE_x |
*/ |
void * |
util_make_fs_blit_msaa_stencil(struct pipe_context *pipe, |
unsigned tgsi_tex) |
{ |
return util_make_fs_blit_msaa_gen(pipe, tgsi_tex, |
"STENCIL", ".y"); |
} |
/** |
* Make a fragment shader that sets the output depth and stencil to depth |
* and stencil values fetched from two multisample textures / samplers. |
* The sizes of both textures should match (it should be one depth-stencil |
* texture). |
* \param tex_target one of PIPE_TEXTURE_x |
*/ |
void * |
util_make_fs_blit_msaa_depthstencil(struct pipe_context *pipe, |
unsigned tgsi_tex) |
{ |
static const char shader_templ[] = |
"FRAG\n" |
"DCL IN[0], GENERIC[0], LINEAR\n" |
"DCL SAMP[0..1]\n" |
"DCL OUT[0], POSITION\n" |
"DCL OUT[1], STENCIL\n" |
"DCL TEMP[0]\n" |
"F2U TEMP[0], IN[0]\n" |
"TXF OUT[0].z, TEMP[0], SAMP[0], %s\n" |
"TXF OUT[1].y, TEMP[0], SAMP[1], %s\n" |
"END\n"; |
const char *type = tgsi_texture_names[tgsi_tex]; |
char text[sizeof(shader_templ)+100]; |
struct tgsi_token tokens[1000]; |
struct pipe_shader_state state = {tokens}; |
assert(tgsi_tex == TGSI_TEXTURE_2D_MSAA || |
tgsi_tex == TGSI_TEXTURE_2D_ARRAY_MSAA); |
sprintf(text, shader_templ, type, type); |
if (!tgsi_text_translate(text, tokens, Elements(tokens))) { |
assert(0); |
return NULL; |
} |
#if 0 |
tgsi_dump(state.tokens, 0); |
#endif |
return pipe->create_fs_state(pipe, &state); |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_simple_shaders.h |
---|
0,0 → 1,130 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* 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 TUNGSTEN GRAPHICS 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_SIMPLE_SHADERS_H |
#define U_SIMPLE_SHADERS_H |
#include "pipe/p_compiler.h" |
struct pipe_context; |
struct pipe_shader_state; |
struct pipe_stream_output_info; |
#ifdef __cplusplus |
extern "C" { |
#endif |
extern void * |
util_make_vertex_passthrough_shader(struct pipe_context *pipe, |
uint num_attribs, |
const uint *semantic_names, |
const uint *semantic_indexes); |
extern void * |
util_make_vertex_passthrough_shader_with_so(struct pipe_context *pipe, |
uint num_attribs, |
const uint *semantic_names, |
const uint *semantic_indexes, |
const struct pipe_stream_output_info *so); |
extern void * |
util_make_fragment_tex_shader_writemask(struct pipe_context *pipe, |
unsigned tex_target, |
unsigned interp_mode, |
unsigned writemask); |
extern void * |
util_make_fragment_tex_shader(struct pipe_context *pipe, unsigned tex_target, |
unsigned interp_mode); |
extern void * |
util_make_fragment_tex_shader_writedepth(struct pipe_context *pipe, |
unsigned tex_target, |
unsigned interp_mode); |
extern void * |
util_make_fragment_tex_shader_writedepthstencil(struct pipe_context *pipe, |
unsigned tex_target, |
unsigned interp_mode); |
extern void * |
util_make_fragment_tex_shader_writestencil(struct pipe_context *pipe, |
unsigned tex_target, |
unsigned interp_mode); |
extern void * |
util_make_fragment_passthrough_shader(struct pipe_context *pipe, |
int input_semantic, |
int input_interpolate, |
boolean write_all_cbufs); |
extern void * |
util_make_empty_fragment_shader(struct pipe_context *pipe); |
extern void * |
util_make_fragment_cloneinput_shader(struct pipe_context *pipe, int num_cbufs, |
int input_semantic, |
int input_interpolate); |
extern void * |
util_make_fs_blit_msaa_color(struct pipe_context *pipe, |
unsigned tgsi_tex); |
extern void * |
util_make_fs_blit_msaa_depth(struct pipe_context *pipe, |
unsigned tgsi_tex); |
extern void * |
util_make_fs_blit_msaa_depthstencil(struct pipe_context *pipe, |
unsigned tgsi_tex); |
void * |
util_make_fs_blit_msaa_stencil(struct pipe_context *pipe, |
unsigned tgsi_tex); |
#ifdef __cplusplus |
} |
#endif |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_slab.c |
---|
0,0 → 1,171 |
/* |
* Copyright 2010 Marek Olšák <maraeo@gmail.com> |
* |
* 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 |
* on 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 |
* THE AUTHOR(S) AND/OR THEIR 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_slab.h" |
#include "util/u_math.h" |
#include "util/u_memory.h" |
#include "util/u_simple_list.h" |
#include <stdio.h> |
#define UTIL_SLAB_MAGIC 0xcafe4321 |
/* The block is either allocated memory or free space. */ |
struct util_slab_block { |
/* The header. */ |
/* The first next free block. */ |
struct util_slab_block *next_free; |
intptr_t magic; |
/* Memory after the last member is dedicated to the block itself. |
* The allocated size is always larger than this structure. */ |
}; |
static struct util_slab_block * |
util_slab_get_block(struct util_slab_mempool *pool, |
struct util_slab_page *page, unsigned index) |
{ |
return (struct util_slab_block*) |
((uint8_t*)page + sizeof(struct util_slab_page) + |
(pool->block_size * index)); |
} |
static void util_slab_add_new_page(struct util_slab_mempool *pool) |
{ |
struct util_slab_page *page; |
struct util_slab_block *block; |
unsigned i; |
page = MALLOC(pool->page_size); |
insert_at_tail(&pool->list, page); |
/* Mark all blocks as free. */ |
for (i = 0; i < pool->num_blocks-1; i++) { |
block = util_slab_get_block(pool, page, i); |
block->next_free = util_slab_get_block(pool, page, i+1); |
block->magic = UTIL_SLAB_MAGIC; |
} |
block = util_slab_get_block(pool, page, pool->num_blocks-1); |
block->next_free = pool->first_free; |
block->magic = UTIL_SLAB_MAGIC; |
pool->first_free = util_slab_get_block(pool, page, 0); |
pool->num_pages++; |
#if 0 |
fprintf(stderr, "New page! Num of pages: %i\n", pool->num_pages); |
#endif |
} |
static void *util_slab_alloc_st(struct util_slab_mempool *pool) |
{ |
struct util_slab_block *block; |
if (!pool->first_free) |
util_slab_add_new_page(pool); |
block = pool->first_free; |
assert(block->magic == UTIL_SLAB_MAGIC); |
pool->first_free = block->next_free; |
return (uint8_t*)block + sizeof(struct util_slab_block); |
} |
static void util_slab_free_st(struct util_slab_mempool *pool, void *ptr) |
{ |
struct util_slab_block *block = |
(struct util_slab_block*) |
((uint8_t*)ptr - sizeof(struct util_slab_block)); |
assert(block->magic == UTIL_SLAB_MAGIC); |
block->next_free = pool->first_free; |
pool->first_free = block; |
} |
static void *util_slab_alloc_mt(struct util_slab_mempool *pool) |
{ |
void *mem; |
pipe_mutex_lock(pool->mutex); |
mem = util_slab_alloc_st(pool); |
pipe_mutex_unlock(pool->mutex); |
return mem; |
} |
static void util_slab_free_mt(struct util_slab_mempool *pool, void *ptr) |
{ |
pipe_mutex_lock(pool->mutex); |
util_slab_free_st(pool, ptr); |
pipe_mutex_unlock(pool->mutex); |
} |
void util_slab_set_thread_safety(struct util_slab_mempool *pool, |
enum util_slab_threading threading) |
{ |
pool->threading = threading; |
if (threading) { |
pool->alloc = util_slab_alloc_mt; |
pool->free = util_slab_free_mt; |
} else { |
pool->alloc = util_slab_alloc_st; |
pool->free = util_slab_free_st; |
} |
} |
void util_slab_create(struct util_slab_mempool *pool, |
unsigned item_size, |
unsigned num_blocks, |
enum util_slab_threading threading) |
{ |
item_size = align(item_size, sizeof(intptr_t)); |
pool->num_pages = 0; |
pool->num_blocks = num_blocks; |
pool->block_size = sizeof(struct util_slab_block) + item_size; |
pool->block_size = align(pool->block_size, sizeof(intptr_t)); |
pool->page_size = sizeof(struct util_slab_page) + |
num_blocks * pool->block_size; |
pool->first_free = NULL; |
make_empty_list(&pool->list); |
pipe_mutex_init(pool->mutex); |
util_slab_set_thread_safety(pool, threading); |
} |
void util_slab_destroy(struct util_slab_mempool *pool) |
{ |
struct util_slab_page *page, *temp; |
if (pool->list.next) { |
foreach_s(page, temp, &pool->list) { |
remove_from_list(page); |
FREE(page); |
} |
} |
pipe_mutex_destroy(pool->mutex); |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_slab.h |
---|
0,0 → 1,87 |
/* |
* Copyright 2010 Marek Olšák <maraeo@gmail.com> |
* |
* 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 |
* on 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 |
* THE AUTHOR(S) AND/OR THEIR 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. */ |
/** |
* @file |
* Simple slab allocator for equally sized memory allocations. |
* util_slab_alloc and util_slab_free have time complexity in O(1). |
* |
* Good for allocations which have very low lifetime and are allocated |
* and freed very often. Use a profiler first to know if it's worth using it! |
* |
* Candidates: transfer_map |
* |
* @author Marek Olšák |
*/ |
#ifndef U_SLAB_H |
#define U_SLAB_H |
#include "os/os_thread.h" |
enum util_slab_threading { |
UTIL_SLAB_SINGLETHREADED = FALSE, |
UTIL_SLAB_MULTITHREADED = TRUE |
}; |
/* The page is an array of blocks (allocations). */ |
struct util_slab_page { |
/* The header (linked-list pointers). */ |
struct util_slab_page *prev, *next; |
/* Memory after the last member is dedicated to the page itself. |
* The allocated size is always larger than this structure. */ |
}; |
struct util_slab_mempool { |
/* Public members. */ |
void *(*alloc)(struct util_slab_mempool *pool); |
void (*free)(struct util_slab_mempool *pool, void *ptr); |
/* Private members. */ |
struct util_slab_block *first_free; |
struct util_slab_page list; |
unsigned block_size; |
unsigned page_size; |
unsigned num_blocks; |
unsigned num_pages; |
enum util_slab_threading threading; |
pipe_mutex mutex; |
}; |
void util_slab_create(struct util_slab_mempool *pool, |
unsigned item_size, |
unsigned num_blocks, |
enum util_slab_threading threading); |
void util_slab_destroy(struct util_slab_mempool *pool); |
void util_slab_set_thread_safety(struct util_slab_mempool *pool, |
enum util_slab_threading threading); |
#define util_slab_alloc(pool) (pool)->alloc(pool) |
#define util_slab_free(pool, ptr) (pool)->free(pool, ptr) |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_snprintf.c |
---|
0,0 → 1,1489 |
/* |
* Copyright (c) 1995 Patrick Powell. |
* |
* This code is based on code written by Patrick Powell <papowell@astart.com>. |
* It may be used for any purpose as long as this notice remains intact on all |
* source code distributions. |
*/ |
/* |
* Copyright (c) 2008 Holger Weiss. |
* |
* This version of the code is maintained by Holger Weiss <holger@jhweiss.de>. |
* My changes to the code may freely be used, modified and/or redistributed for |
* any purpose. It would be nice if additions and fixes to this file (including |
* trivial code cleanups) would be sent back in order to let me include them in |
* the version available at <http://www.jhweiss.de/software/snprintf.html>. |
* However, this is not a requirement for using or redistributing (possibly |
* modified) versions of this file, nor is leaving this notice intact mandatory. |
*/ |
/* |
* History |
* |
* 2008-01-20 Holger Weiss <holger@jhweiss.de> for C99-snprintf 1.1: |
* |
* Fixed the detection of infinite floating point values on IRIX (and |
* possibly other systems) and applied another few minor cleanups. |
* |
* 2008-01-06 Holger Weiss <holger@jhweiss.de> for C99-snprintf 1.0: |
* |
* Added a lot of new features, fixed many bugs, and incorporated various |
* improvements done by Andrew Tridgell <tridge@samba.org>, Russ Allbery |
* <rra@stanford.edu>, Hrvoje Niksic <hniksic@xemacs.org>, Damien Miller |
* <djm@mindrot.org>, and others for the Samba, INN, Wget, and OpenSSH |
* projects. The additions include: support the "e", "E", "g", "G", and |
* "F" conversion specifiers (and use conversion style "f" or "F" for the |
* still unsupported "a" and "A" specifiers); support the "hh", "ll", "j", |
* "t", and "z" length modifiers; support the "#" flag and the (non-C99) |
* "'" flag; use localeconv(3) (if available) to get both the current |
* locale's decimal point character and the separator between groups of |
* digits; fix the handling of various corner cases of field width and |
* precision specifications; fix various floating point conversion bugs; |
* handle infinite and NaN floating point values; don't attempt to write to |
* the output buffer (which may be NULL) if a size of zero was specified; |
* check for integer overflow of the field width, precision, and return |
* values and during the floating point conversion; use the OUTCHAR() macro |
* instead of a function for better performance; provide asprintf(3) and |
* vasprintf(3) functions; add new test cases. The replacement functions |
* have been renamed to use an "rpl_" prefix, the function calls in the |
* main project (and in this file) must be redefined accordingly for each |
* replacement function which is needed (by using Autoconf or other means). |
* Various other minor improvements have been applied and the coding style |
* was cleaned up for consistency. |
* |
* 2007-07-23 Holger Weiss <holger@jhweiss.de> for Mutt 1.5.13: |
* |
* C99 compliant snprintf(3) and vsnprintf(3) functions return the number |
* of characters that would have been written to a sufficiently sized |
* buffer (excluding the '\0'). The original code simply returned the |
* length of the resulting output string, so that's been fixed. |
* |
* 1998-03-05 Michael Elkins <me@mutt.org> for Mutt 0.90.8: |
* |
* The original code assumed that both snprintf(3) and vsnprintf(3) were |
* missing. Some systems only have snprintf(3) but not vsnprintf(3), so |
* the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. |
* |
* 1998-01-27 Thomas Roessler <roessler@does-not-exist.org> for Mutt 0.89i: |
* |
* The PGP code was using unsigned hexadecimal formats. Unfortunately, |
* unsigned formats simply didn't work. |
* |
* 1997-10-22 Brandon Long <blong@fiction.net> for Mutt 0.87.1: |
* |
* Ok, added some minimal floating point support, which means this probably |
* requires libm on most operating systems. Don't yet support the exponent |
* (e,E) and sigfig (g,G). Also, fmtint() was pretty badly broken, it just |
* wasn't being exercised in ways which showed it, so that's been fixed. |
* Also, formatted the code to Mutt conventions, and removed dead code left |
* over from the original. Also, there is now a builtin-test, run with: |
* gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm && ./snprintf |
* |
* 2996-09-15 Brandon Long <blong@fiction.net> for Mutt 0.43: |
* |
* This was ugly. It is still ugly. I opted out of floating point |
* numbers, but the formatter understands just about everything from the |
* normal C string format, at least as far as I can tell from the Solaris |
* 2.5 printf(3S) man page. |
*/ |
/* |
* ToDo |
* |
* - Add wide character support. |
* - Add support for "%a" and "%A" conversions. |
* - Create test routines which predefine the expected results. Our test cases |
* usually expose bugs in system implementations rather than in ours :-) |
*/ |
/* |
* Usage |
* |
* 1) The following preprocessor macros should be defined to 1 if the feature or |
* file in question is available on the target system (by using Autoconf or |
* other means), though basic functionality should be available as long as |
* HAVE_STDARG_H and HAVE_STDLIB_H are defined correctly: |
* |
* HAVE_VSNPRINTF |
* HAVE_SNPRINTF |
* HAVE_VASPRINTF |
* HAVE_ASPRINTF |
* HAVE_STDARG_H |
* HAVE_STDDEF_H |
* HAVE_STDINT_H |
* HAVE_STDLIB_H |
* HAVE_INTTYPES_H |
* HAVE_LOCALE_H |
* HAVE_LOCALECONV |
* HAVE_LCONV_DECIMAL_POINT |
* HAVE_LCONV_THOUSANDS_SEP |
* HAVE_LONG_DOUBLE |
* HAVE_LONG_LONG_INT |
* HAVE_UNSIGNED_LONG_LONG_INT |
* HAVE_INTMAX_T |
* HAVE_UINTMAX_T |
* HAVE_UINTPTR_T |
* HAVE_PTRDIFF_T |
* HAVE_VA_COPY |
* HAVE___VA_COPY |
* |
* 2) The calls to the functions which should be replaced must be redefined |
* throughout the project files (by using Autoconf or other means): |
* |
* #define vsnprintf rpl_vsnprintf |
* #define snprintf rpl_snprintf |
* #define vasprintf rpl_vasprintf |
* #define asprintf rpl_asprintf |
* |
* 3) The required replacement functions should be declared in some header file |
* included throughout the project files: |
* |
* #if HAVE_CONFIG_H |
* #include <config.h> |
* #endif |
* #if HAVE_STDARG_H |
* #include <stdarg.h> |
* #if !HAVE_VSNPRINTF |
* int rpl_vsnprintf(char *, size_t, const char *, va_list); |
* #endif |
* #if !HAVE_SNPRINTF |
* int rpl_snprintf(char *, size_t, const char *, ...); |
* #endif |
* #if !HAVE_VASPRINTF |
* int rpl_vasprintf(char **, const char *, va_list); |
* #endif |
* #if !HAVE_ASPRINTF |
* int rpl_asprintf(char **, const char *, ...); |
* #endif |
* #endif |
* |
* Autoconf macros for handling step 1 and step 2 are available at |
* <http://www.jhweiss.de/software/snprintf.html>. |
*/ |
#include "pipe/p_config.h" |
#if HAVE_CONFIG_H |
#include <config.h> |
#else |
#ifdef _MSC_VER |
#define vsnprintf util_vsnprintf |
#define snprintf util_snprintf |
#define HAVE_VSNPRINTF 0 |
#define HAVE_SNPRINTF 0 |
#define HAVE_VASPRINTF 1 /* not needed */ |
#define HAVE_ASPRINTF 1 /* not needed */ |
#define HAVE_STDARG_H 1 |
#define HAVE_STDDEF_H 1 |
#define HAVE_STDINT_H 0 |
#define HAVE_STDLIB_H 1 |
#define HAVE_INTTYPES_H 0 |
#define HAVE_LOCALE_H 0 |
#define HAVE_LOCALECONV 0 |
#define HAVE_LCONV_DECIMAL_POINT 0 |
#define HAVE_LCONV_THOUSANDS_SEP 0 |
#define HAVE_LONG_DOUBLE 0 |
#define HAVE_LONG_LONG_INT 1 |
#define HAVE_UNSIGNED_LONG_LONG_INT 1 |
#define HAVE_INTMAX_T 0 |
#define HAVE_UINTMAX_T 0 |
#define HAVE_UINTPTR_T 1 |
#define HAVE_PTRDIFF_T 1 |
#define HAVE_VA_COPY 0 |
#define HAVE___VA_COPY 0 |
#else |
#define HAVE_VSNPRINTF 1 |
#define HAVE_SNPRINTF 1 |
#define HAVE_VASPRINTF 1 |
#define HAVE_ASPRINTF 1 |
#endif |
#endif /* HAVE_CONFIG_H */ |
#if !HAVE_SNPRINTF || !HAVE_VSNPRINTF || !HAVE_ASPRINTF || !HAVE_VASPRINTF |
#include <stdio.h> /* For NULL, size_t, vsnprintf(3), and vasprintf(3). */ |
#ifdef VA_START |
#undef VA_START |
#endif /* defined(VA_START) */ |
#ifdef VA_SHIFT |
#undef VA_SHIFT |
#endif /* defined(VA_SHIFT) */ |
#if HAVE_STDARG_H |
#include <stdarg.h> |
#define VA_START(ap, last) va_start(ap, last) |
#define VA_SHIFT(ap, value, type) /* No-op for ANSI C. */ |
#else /* Assume <varargs.h> is available. */ |
#include <varargs.h> |
#define VA_START(ap, last) va_start(ap) /* "last" is ignored. */ |
#define VA_SHIFT(ap, value, type) value = va_arg(ap, type) |
#endif /* HAVE_STDARG_H */ |
#if !HAVE_VASPRINTF |
#if HAVE_STDLIB_H |
#include <stdlib.h> /* For malloc(3). */ |
#endif /* HAVE_STDLIB_H */ |
#ifdef VA_COPY |
#undef VA_COPY |
#endif /* defined(VA_COPY) */ |
#ifdef VA_END_COPY |
#undef VA_END_COPY |
#endif /* defined(VA_END_COPY) */ |
#if HAVE_VA_COPY |
#define VA_COPY(dest, src) va_copy(dest, src) |
#define VA_END_COPY(ap) va_end(ap) |
#elif HAVE___VA_COPY |
#define VA_COPY(dest, src) __va_copy(dest, src) |
#define VA_END_COPY(ap) va_end(ap) |
#else |
#define VA_COPY(dest, src) (void)mymemcpy(&dest, &src, sizeof(va_list)) |
#define VA_END_COPY(ap) /* No-op. */ |
#define NEED_MYMEMCPY 1 |
static void *mymemcpy(void *, void *, size_t); |
#endif /* HAVE_VA_COPY */ |
#endif /* !HAVE_VASPRINTF */ |
#if !HAVE_VSNPRINTF |
#include <limits.h> /* For *_MAX. */ |
#if HAVE_INTTYPES_H |
#include <inttypes.h> /* For intmax_t (if not defined in <stdint.h>). */ |
#endif /* HAVE_INTTYPES_H */ |
#if HAVE_LOCALE_H |
#include <locale.h> /* For localeconv(3). */ |
#endif /* HAVE_LOCALE_H */ |
#if HAVE_STDDEF_H |
#include <stddef.h> /* For ptrdiff_t. */ |
#endif /* HAVE_STDDEF_H */ |
#if HAVE_STDINT_H |
#include <stdint.h> /* For intmax_t. */ |
#endif /* HAVE_STDINT_H */ |
/* Support for unsigned long long int. We may also need ULLONG_MAX. */ |
#ifndef ULONG_MAX /* We may need ULONG_MAX as a fallback. */ |
#ifdef UINT_MAX |
#define ULONG_MAX UINT_MAX |
#else |
#define ULONG_MAX INT_MAX |
#endif /* defined(UINT_MAX) */ |
#endif /* !defined(ULONG_MAX) */ |
#ifdef ULLONG |
#undef ULLONG |
#endif /* defined(ULLONG) */ |
#if HAVE_UNSIGNED_LONG_LONG_INT |
#define ULLONG unsigned long long int |
#ifndef ULLONG_MAX |
#define ULLONG_MAX ULONG_MAX |
#endif /* !defined(ULLONG_MAX) */ |
#else |
#define ULLONG unsigned long int |
#ifdef ULLONG_MAX |
#undef ULLONG_MAX |
#endif /* defined(ULLONG_MAX) */ |
#define ULLONG_MAX ULONG_MAX |
#endif /* HAVE_LONG_LONG_INT */ |
/* Support for uintmax_t. We also need UINTMAX_MAX. */ |
#ifdef UINTMAX_T |
#undef UINTMAX_T |
#endif /* defined(UINTMAX_T) */ |
#if HAVE_UINTMAX_T || defined(uintmax_t) |
#define UINTMAX_T uintmax_t |
#ifndef UINTMAX_MAX |
#define UINTMAX_MAX ULLONG_MAX |
#endif /* !defined(UINTMAX_MAX) */ |
#else |
#define UINTMAX_T ULLONG |
#ifdef UINTMAX_MAX |
#undef UINTMAX_MAX |
#endif /* defined(UINTMAX_MAX) */ |
#define UINTMAX_MAX ULLONG_MAX |
#endif /* HAVE_UINTMAX_T || defined(uintmax_t) */ |
/* Support for long double. */ |
#ifndef LDOUBLE |
#if HAVE_LONG_DOUBLE |
#define LDOUBLE long double |
#else |
#define LDOUBLE double |
#endif /* HAVE_LONG_DOUBLE */ |
#endif /* !defined(LDOUBLE) */ |
/* Support for long long int. */ |
#ifndef LLONG |
#if HAVE_LONG_LONG_INT |
#define LLONG long long int |
#else |
#define LLONG long int |
#endif /* HAVE_LONG_LONG_INT */ |
#endif /* !defined(LLONG) */ |
/* Support for intmax_t. */ |
#ifndef INTMAX_T |
#if HAVE_INTMAX_T || defined(intmax_t) |
#define INTMAX_T intmax_t |
#else |
#define INTMAX_T LLONG |
#endif /* HAVE_INTMAX_T || defined(intmax_t) */ |
#endif /* !defined(INTMAX_T) */ |
/* Support for uintptr_t. */ |
#ifndef UINTPTR_T |
#if HAVE_UINTPTR_T || defined(uintptr_t) |
#define UINTPTR_T uintptr_t |
#else |
#define UINTPTR_T unsigned long int |
#endif /* HAVE_UINTPTR_T || defined(uintptr_t) */ |
#endif /* !defined(UINTPTR_T) */ |
/* WinCE5.0 does not have uintptr_t defined */ |
#if (_WIN32_WCE < 600) |
#ifdef UINTPTR_T |
#undef UINTPTR_T |
#endif |
#define UINTPTR_T unsigned long int |
#endif |
/* Support for ptrdiff_t. */ |
#ifndef PTRDIFF_T |
#if HAVE_PTRDIFF_T || defined(ptrdiff_t) |
#define PTRDIFF_T ptrdiff_t |
#else |
#define PTRDIFF_T long int |
#endif /* HAVE_PTRDIFF_T || defined(ptrdiff_t) */ |
#endif /* !defined(PTRDIFF_T) */ |
/* |
* We need an unsigned integer type corresponding to ptrdiff_t (cf. C99: |
* 7.19.6.1, 7). However, we'll simply use PTRDIFF_T and convert it to an |
* unsigned type if necessary. This should work just fine in practice. |
*/ |
#ifndef UPTRDIFF_T |
#define UPTRDIFF_T PTRDIFF_T |
#endif /* !defined(UPTRDIFF_T) */ |
/* |
* We need a signed integer type corresponding to size_t (cf. C99: 7.19.6.1, 7). |
* However, we'll simply use size_t and convert it to a signed type if |
* necessary. This should work just fine in practice. |
*/ |
#ifndef SSIZE_T |
#define SSIZE_T size_t |
#endif /* !defined(SSIZE_T) */ |
/* Either ERANGE or E2BIG should be available everywhere. */ |
#ifndef ERANGE |
#define ERANGE E2BIG |
#endif /* !defined(ERANGE) */ |
#ifndef EOVERFLOW |
#define EOVERFLOW ERANGE |
#endif /* !defined(EOVERFLOW) */ |
/* |
* Buffer size to hold the octal string representation of UINT128_MAX without |
* nul-termination ("3777777777777777777777777777777777777777777"). |
*/ |
#ifdef MAX_CONVERT_LENGTH |
#undef MAX_CONVERT_LENGTH |
#endif /* defined(MAX_CONVERT_LENGTH) */ |
#define MAX_CONVERT_LENGTH 43 |
/* Format read states. */ |
#define PRINT_S_DEFAULT 0 |
#define PRINT_S_FLAGS 1 |
#define PRINT_S_WIDTH 2 |
#define PRINT_S_DOT 3 |
#define PRINT_S_PRECISION 4 |
#define PRINT_S_MOD 5 |
#define PRINT_S_CONV 6 |
/* Format flags. */ |
#define PRINT_F_MINUS (1 << 0) |
#define PRINT_F_PLUS (1 << 1) |
#define PRINT_F_SPACE (1 << 2) |
#define PRINT_F_NUM (1 << 3) |
#define PRINT_F_ZERO (1 << 4) |
#define PRINT_F_QUOTE (1 << 5) |
#define PRINT_F_UP (1 << 6) |
#define PRINT_F_UNSIGNED (1 << 7) |
#define PRINT_F_TYPE_G (1 << 8) |
#define PRINT_F_TYPE_E (1 << 9) |
/* Conversion flags. */ |
#define PRINT_C_CHAR 1 |
#define PRINT_C_SHORT 2 |
#define PRINT_C_LONG 3 |
#define PRINT_C_LLONG 4 |
#define PRINT_C_LDOUBLE 5 |
#define PRINT_C_SIZE 6 |
#define PRINT_C_PTRDIFF 7 |
#define PRINT_C_INTMAX 8 |
#ifndef MAX |
#define MAX(x, y) ((x >= y) ? x : y) |
#endif /* !defined(MAX) */ |
#ifndef CHARTOINT |
#define CHARTOINT(ch) (ch - '0') |
#endif /* !defined(CHARTOINT) */ |
#ifndef ISDIGIT |
#define ISDIGIT(ch) ('0' <= (unsigned char)ch && (unsigned char)ch <= '9') |
#endif /* !defined(ISDIGIT) */ |
#ifndef ISNAN |
#define ISNAN(x) (x != x) |
#endif /* !defined(ISNAN) */ |
#ifndef ISINF |
#define ISINF(x) (x != 0.0 && x + x == x) |
#endif /* !defined(ISINF) */ |
#ifdef OUTCHAR |
#undef OUTCHAR |
#endif /* defined(OUTCHAR) */ |
#define OUTCHAR(str, len, size, ch) \ |
do { \ |
if (len + 1 < size) \ |
str[len] = ch; \ |
(len)++; \ |
} while (/* CONSTCOND */ 0) |
static void fmtstr(char *, size_t *, size_t, const char *, int, int, int); |
static void fmtint(char *, size_t *, size_t, INTMAX_T, int, int, int, int); |
static void fmtflt(char *, size_t *, size_t, LDOUBLE, int, int, int, int *); |
static void printsep(char *, size_t *, size_t); |
static int getnumsep(int); |
static int getexponent(LDOUBLE); |
static int convert(UINTMAX_T, char *, size_t, int, int); |
static UINTMAX_T cast(LDOUBLE); |
static UINTMAX_T myround(LDOUBLE); |
static LDOUBLE mypow10(int); |
int |
util_vsnprintf(char *str, size_t size, const char *format, va_list args) |
{ |
LDOUBLE fvalue; |
INTMAX_T value; |
unsigned char cvalue; |
const char *strvalue; |
INTMAX_T *intmaxptr; |
PTRDIFF_T *ptrdiffptr; |
SSIZE_T *sizeptr; |
LLONG *llongptr; |
long int *longptr; |
int *intptr; |
short int *shortptr; |
signed char *charptr; |
size_t len = 0; |
int overflow = 0; |
int base = 0; |
int cflags = 0; |
int flags = 0; |
int width = 0; |
int precision = -1; |
int state = PRINT_S_DEFAULT; |
char ch = *format++; |
/* |
* C99 says: "If `n' is zero, nothing is written, and `s' may be a null |
* pointer." (7.19.6.5, 2) We're forgiving and allow a NULL pointer |
* even if a size larger than zero was specified. At least NetBSD's |
* snprintf(3) does the same, as well as other versions of this file. |
* (Though some of these versions will write to a non-NULL buffer even |
* if a size of zero was specified, which violates the standard.) |
*/ |
if (str == NULL && size != 0) |
size = 0; |
while (ch != '\0') |
switch (state) { |
case PRINT_S_DEFAULT: |
if (ch == '%') |
state = PRINT_S_FLAGS; |
else |
OUTCHAR(str, len, size, ch); |
ch = *format++; |
break; |
case PRINT_S_FLAGS: |
switch (ch) { |
case '-': |
flags |= PRINT_F_MINUS; |
ch = *format++; |
break; |
case '+': |
flags |= PRINT_F_PLUS; |
ch = *format++; |
break; |
case ' ': |
flags |= PRINT_F_SPACE; |
ch = *format++; |
break; |
case '#': |
flags |= PRINT_F_NUM; |
ch = *format++; |
break; |
case '0': |
flags |= PRINT_F_ZERO; |
ch = *format++; |
break; |
case '\'': /* SUSv2 flag (not in C99). */ |
flags |= PRINT_F_QUOTE; |
ch = *format++; |
break; |
default: |
state = PRINT_S_WIDTH; |
break; |
} |
break; |
case PRINT_S_WIDTH: |
if (ISDIGIT(ch)) { |
ch = CHARTOINT(ch); |
if (width > (INT_MAX - ch) / 10) { |
overflow = 1; |
goto out; |
} |
width = 10 * width + ch; |
ch = *format++; |
} else if (ch == '*') { |
/* |
* C99 says: "A negative field width argument is |
* taken as a `-' flag followed by a positive |
* field width." (7.19.6.1, 5) |
*/ |
if ((width = va_arg(args, int)) < 0) { |
flags |= PRINT_F_MINUS; |
width = -width; |
} |
ch = *format++; |
state = PRINT_S_DOT; |
} else |
state = PRINT_S_DOT; |
break; |
case PRINT_S_DOT: |
if (ch == '.') { |
state = PRINT_S_PRECISION; |
ch = *format++; |
} else |
state = PRINT_S_MOD; |
break; |
case PRINT_S_PRECISION: |
if (precision == -1) |
precision = 0; |
if (ISDIGIT(ch)) { |
ch = CHARTOINT(ch); |
if (precision > (INT_MAX - ch) / 10) { |
overflow = 1; |
goto out; |
} |
precision = 10 * precision + ch; |
ch = *format++; |
} else if (ch == '*') { |
/* |
* C99 says: "A negative precision argument is |
* taken as if the precision were omitted." |
* (7.19.6.1, 5) |
*/ |
if ((precision = va_arg(args, int)) < 0) |
precision = -1; |
ch = *format++; |
state = PRINT_S_MOD; |
} else |
state = PRINT_S_MOD; |
break; |
case PRINT_S_MOD: |
switch (ch) { |
case 'h': |
ch = *format++; |
if (ch == 'h') { /* It's a char. */ |
ch = *format++; |
cflags = PRINT_C_CHAR; |
} else |
cflags = PRINT_C_SHORT; |
break; |
case 'l': |
ch = *format++; |
if (ch == 'l') { /* It's a long long. */ |
ch = *format++; |
cflags = PRINT_C_LLONG; |
} else |
cflags = PRINT_C_LONG; |
break; |
case 'L': |
cflags = PRINT_C_LDOUBLE; |
ch = *format++; |
break; |
case 'j': |
cflags = PRINT_C_INTMAX; |
ch = *format++; |
break; |
case 't': |
cflags = PRINT_C_PTRDIFF; |
ch = *format++; |
break; |
case 'z': |
cflags = PRINT_C_SIZE; |
ch = *format++; |
break; |
} |
state = PRINT_S_CONV; |
break; |
case PRINT_S_CONV: |
switch (ch) { |
case 'd': |
/* FALLTHROUGH */ |
case 'i': |
switch (cflags) { |
case PRINT_C_CHAR: |
value = (signed char)va_arg(args, int); |
break; |
case PRINT_C_SHORT: |
value = (short int)va_arg(args, int); |
break; |
case PRINT_C_LONG: |
value = va_arg(args, long int); |
break; |
case PRINT_C_LLONG: |
value = va_arg(args, LLONG); |
break; |
case PRINT_C_SIZE: |
value = va_arg(args, SSIZE_T); |
break; |
case PRINT_C_INTMAX: |
value = va_arg(args, INTMAX_T); |
break; |
case PRINT_C_PTRDIFF: |
value = va_arg(args, PTRDIFF_T); |
break; |
default: |
value = va_arg(args, int); |
break; |
} |
fmtint(str, &len, size, value, 10, width, |
precision, flags); |
break; |
case 'X': |
flags |= PRINT_F_UP; |
/* FALLTHROUGH */ |
case 'x': |
base = 16; |
/* FALLTHROUGH */ |
case 'o': |
if (base == 0) |
base = 8; |
/* FALLTHROUGH */ |
case 'u': |
if (base == 0) |
base = 10; |
flags |= PRINT_F_UNSIGNED; |
switch (cflags) { |
case PRINT_C_CHAR: |
value = (unsigned char)va_arg(args, |
unsigned int); |
break; |
case PRINT_C_SHORT: |
value = (unsigned short int)va_arg(args, |
unsigned int); |
break; |
case PRINT_C_LONG: |
value = va_arg(args, unsigned long int); |
break; |
case PRINT_C_LLONG: |
value = va_arg(args, ULLONG); |
break; |
case PRINT_C_SIZE: |
value = va_arg(args, size_t); |
break; |
case PRINT_C_INTMAX: |
value = va_arg(args, UINTMAX_T); |
break; |
case PRINT_C_PTRDIFF: |
value = va_arg(args, UPTRDIFF_T); |
break; |
default: |
value = va_arg(args, unsigned int); |
break; |
} |
fmtint(str, &len, size, value, base, width, |
precision, flags); |
break; |
case 'A': |
/* Not yet supported, we'll use "%F". */ |
/* FALLTHROUGH */ |
case 'F': |
flags |= PRINT_F_UP; |
case 'a': |
/* Not yet supported, we'll use "%f". */ |
/* FALLTHROUGH */ |
case 'f': |
if (cflags == PRINT_C_LDOUBLE) |
fvalue = va_arg(args, LDOUBLE); |
else |
fvalue = va_arg(args, double); |
fmtflt(str, &len, size, fvalue, width, |
precision, flags, &overflow); |
if (overflow) |
goto out; |
break; |
case 'E': |
flags |= PRINT_F_UP; |
/* FALLTHROUGH */ |
case 'e': |
flags |= PRINT_F_TYPE_E; |
if (cflags == PRINT_C_LDOUBLE) |
fvalue = va_arg(args, LDOUBLE); |
else |
fvalue = va_arg(args, double); |
fmtflt(str, &len, size, fvalue, width, |
precision, flags, &overflow); |
if (overflow) |
goto out; |
break; |
case 'G': |
flags |= PRINT_F_UP; |
/* FALLTHROUGH */ |
case 'g': |
flags |= PRINT_F_TYPE_G; |
if (cflags == PRINT_C_LDOUBLE) |
fvalue = va_arg(args, LDOUBLE); |
else |
fvalue = va_arg(args, double); |
/* |
* If the precision is zero, it is treated as |
* one (cf. C99: 7.19.6.1, 8). |
*/ |
if (precision == 0) |
precision = 1; |
fmtflt(str, &len, size, fvalue, width, |
precision, flags, &overflow); |
if (overflow) |
goto out; |
break; |
case 'c': |
cvalue = (unsigned char)va_arg(args, int); |
OUTCHAR(str, len, size, cvalue); |
break; |
case 's': |
strvalue = va_arg(args, char *); |
fmtstr(str, &len, size, strvalue, width, |
precision, flags); |
break; |
case 'p': |
/* |
* C99 says: "The value of the pointer is |
* converted to a sequence of printing |
* characters, in an implementation-defined |
* manner." (C99: 7.19.6.1, 8) |
*/ |
if ((strvalue = va_arg(args, void *)) == NULL) |
/* |
* We use the glibc format. BSD prints |
* "0x0", SysV "0". |
*/ |
fmtstr(str, &len, size, "(nil)", width, |
-1, flags); |
else { |
/* |
* We use the BSD/glibc format. SysV |
* omits the "0x" prefix (which we emit |
* using the PRINT_F_NUM flag). |
*/ |
flags |= PRINT_F_NUM; |
flags |= PRINT_F_UNSIGNED; |
fmtint(str, &len, size, |
(UINTPTR_T)strvalue, 16, width, |
precision, flags); |
} |
break; |
case 'n': |
switch (cflags) { |
case PRINT_C_CHAR: |
charptr = va_arg(args, signed char *); |
*charptr = (signed char)len; |
break; |
case PRINT_C_SHORT: |
shortptr = va_arg(args, short int *); |
*shortptr = (short int)len; |
break; |
case PRINT_C_LONG: |
longptr = va_arg(args, long int *); |
*longptr = (long int)len; |
break; |
case PRINT_C_LLONG: |
llongptr = va_arg(args, LLONG *); |
*llongptr = (LLONG)len; |
break; |
case PRINT_C_SIZE: |
/* |
* C99 says that with the "z" length |
* modifier, "a following `n' conversion |
* specifier applies to a pointer to a |
* signed integer type corresponding to |
* size_t argument." (7.19.6.1, 7) |
*/ |
sizeptr = va_arg(args, SSIZE_T *); |
*sizeptr = len; |
break; |
case PRINT_C_INTMAX: |
intmaxptr = va_arg(args, INTMAX_T *); |
*intmaxptr = len; |
break; |
case PRINT_C_PTRDIFF: |
ptrdiffptr = va_arg(args, PTRDIFF_T *); |
*ptrdiffptr = len; |
break; |
default: |
intptr = va_arg(args, int *); |
*intptr = (int)len; |
break; |
} |
break; |
case '%': /* Print a "%" character verbatim. */ |
OUTCHAR(str, len, size, ch); |
break; |
default: /* Skip other characters. */ |
break; |
} |
ch = *format++; |
state = PRINT_S_DEFAULT; |
base = cflags = flags = width = 0; |
precision = -1; |
break; |
} |
out: |
if (len < size) |
str[len] = '\0'; |
else if (size > 0) |
str[size - 1] = '\0'; |
if (overflow || len >= INT_MAX) { |
return -1; |
} |
return (int)len; |
} |
static void |
fmtstr(char *str, size_t *len, size_t size, const char *value, int width, |
int precision, int flags) |
{ |
int padlen, strln; /* Amount to pad. */ |
int noprecision = (precision == -1); |
if (value == NULL) /* We're forgiving. */ |
value = "(null)"; |
/* If a precision was specified, don't read the string past it. */ |
for (strln = 0; value[strln] != '\0' && |
(noprecision || strln < precision); strln++) |
continue; |
if ((padlen = width - strln) < 0) |
padlen = 0; |
if (flags & PRINT_F_MINUS) /* Left justify. */ |
padlen = -padlen; |
while (padlen > 0) { /* Leading spaces. */ |
OUTCHAR(str, *len, size, ' '); |
padlen--; |
} |
while (*value != '\0' && (noprecision || precision-- > 0)) { |
OUTCHAR(str, *len, size, *value); |
value++; |
} |
while (padlen < 0) { /* Trailing spaces. */ |
OUTCHAR(str, *len, size, ' '); |
padlen++; |
} |
} |
static void |
fmtint(char *str, size_t *len, size_t size, INTMAX_T value, int base, int width, |
int precision, int flags) |
{ |
UINTMAX_T uvalue; |
char iconvert[MAX_CONVERT_LENGTH]; |
char sign = 0; |
char hexprefix = 0; |
int spadlen = 0; /* Amount to space pad. */ |
int zpadlen = 0; /* Amount to zero pad. */ |
int pos; |
int separators = (flags & PRINT_F_QUOTE); |
int noprecision = (precision == -1); |
if (flags & PRINT_F_UNSIGNED) |
uvalue = value; |
else { |
uvalue = (value >= 0) ? value : -value; |
if (value < 0) |
sign = '-'; |
else if (flags & PRINT_F_PLUS) /* Do a sign. */ |
sign = '+'; |
else if (flags & PRINT_F_SPACE) |
sign = ' '; |
} |
pos = convert(uvalue, iconvert, sizeof(iconvert), base, |
flags & PRINT_F_UP); |
if (flags & PRINT_F_NUM && uvalue != 0) { |
/* |
* C99 says: "The result is converted to an `alternative form'. |
* For `o' conversion, it increases the precision, if and only |
* if necessary, to force the first digit of the result to be a |
* zero (if the value and precision are both 0, a single 0 is |
* printed). For `x' (or `X') conversion, a nonzero result has |
* `0x' (or `0X') prefixed to it." (7.19.6.1, 6) |
*/ |
switch (base) { |
case 8: |
if (precision <= pos) |
precision = pos + 1; |
break; |
case 16: |
hexprefix = (flags & PRINT_F_UP) ? 'X' : 'x'; |
break; |
} |
} |
if (separators) /* Get the number of group separators we'll print. */ |
separators = getnumsep(pos); |
zpadlen = precision - pos - separators; |
spadlen = width /* Minimum field width. */ |
- separators /* Number of separators. */ |
- MAX(precision, pos) /* Number of integer digits. */ |
- ((sign != 0) ? 1 : 0) /* Will we print a sign? */ |
- ((hexprefix != 0) ? 2 : 0); /* Will we print a prefix? */ |
if (zpadlen < 0) |
zpadlen = 0; |
if (spadlen < 0) |
spadlen = 0; |
/* |
* C99 says: "If the `0' and `-' flags both appear, the `0' flag is |
* ignored. For `d', `i', `o', `u', `x', and `X' conversions, if a |
* precision is specified, the `0' flag is ignored." (7.19.6.1, 6) |
*/ |
if (flags & PRINT_F_MINUS) /* Left justify. */ |
spadlen = -spadlen; |
else if (flags & PRINT_F_ZERO && noprecision) { |
zpadlen += spadlen; |
spadlen = 0; |
} |
while (spadlen > 0) { /* Leading spaces. */ |
OUTCHAR(str, *len, size, ' '); |
spadlen--; |
} |
if (sign != 0) /* Sign. */ |
OUTCHAR(str, *len, size, sign); |
if (hexprefix != 0) { /* A "0x" or "0X" prefix. */ |
OUTCHAR(str, *len, size, '0'); |
OUTCHAR(str, *len, size, hexprefix); |
} |
while (zpadlen > 0) { /* Leading zeros. */ |
OUTCHAR(str, *len, size, '0'); |
zpadlen--; |
} |
while (pos > 0) { /* The actual digits. */ |
pos--; |
OUTCHAR(str, *len, size, iconvert[pos]); |
if (separators > 0 && pos > 0 && pos % 3 == 0) |
printsep(str, len, size); |
} |
while (spadlen < 0) { /* Trailing spaces. */ |
OUTCHAR(str, *len, size, ' '); |
spadlen++; |
} |
} |
static void |
fmtflt(char *str, size_t *len, size_t size, LDOUBLE fvalue, int width, |
int precision, int flags, int *overflow) |
{ |
LDOUBLE ufvalue; |
UINTMAX_T intpart; |
UINTMAX_T fracpart; |
UINTMAX_T mask; |
const char *infnan = NULL; |
char iconvert[MAX_CONVERT_LENGTH]; |
char fconvert[MAX_CONVERT_LENGTH]; |
char econvert[4]; /* "e-12" (without nul-termination). */ |
char esign = 0; |
char sign = 0; |
int leadfraczeros = 0; |
int exponent = 0; |
int emitpoint = 0; |
int omitzeros = 0; |
int omitcount = 0; |
int padlen = 0; |
int epos = 0; |
int fpos = 0; |
int ipos = 0; |
int separators = (flags & PRINT_F_QUOTE); |
int estyle = (flags & PRINT_F_TYPE_E); |
#if HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT |
struct lconv *lc = localeconv(); |
#endif /* HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT */ |
/* |
* AIX' man page says the default is 0, but C99 and at least Solaris' |
* and NetBSD's man pages say the default is 6, and sprintf(3) on AIX |
* defaults to 6. |
*/ |
if (precision == -1) |
precision = 6; |
if (fvalue < 0.0) |
sign = '-'; |
else if (flags & PRINT_F_PLUS) /* Do a sign. */ |
sign = '+'; |
else if (flags & PRINT_F_SPACE) |
sign = ' '; |
if (ISNAN(fvalue)) |
infnan = (flags & PRINT_F_UP) ? "NAN" : "nan"; |
else if (ISINF(fvalue)) |
infnan = (flags & PRINT_F_UP) ? "INF" : "inf"; |
if (infnan != NULL) { |
if (sign != 0) |
iconvert[ipos++] = sign; |
while (*infnan != '\0') |
iconvert[ipos++] = *infnan++; |
fmtstr(str, len, size, iconvert, width, ipos, flags); |
return; |
} |
/* "%e" (or "%E") or "%g" (or "%G") conversion. */ |
if (flags & PRINT_F_TYPE_E || flags & PRINT_F_TYPE_G) { |
if (flags & PRINT_F_TYPE_G) { |
/* |
* For "%g" (and "%G") conversions, the precision |
* specifies the number of significant digits, which |
* includes the digits in the integer part. The |
* conversion will or will not be using "e-style" (like |
* "%e" or "%E" conversions) depending on the precision |
* and on the exponent. However, the exponent can be |
* affected by rounding the converted value, so we'll |
* leave this decision for later. Until then, we'll |
* assume that we're going to do an "e-style" conversion |
* (in order to get the exponent calculated). For |
* "e-style", the precision must be decremented by one. |
*/ |
precision--; |
/* |
* For "%g" (and "%G") conversions, trailing zeros are |
* removed from the fractional portion of the result |
* unless the "#" flag was specified. |
*/ |
if (!(flags & PRINT_F_NUM)) |
omitzeros = 1; |
} |
exponent = getexponent(fvalue); |
estyle = 1; |
} |
again: |
/* |
* Sorry, we only support 9, 19, or 38 digits (that is, the number of |
* digits of the 32-bit, the 64-bit, or the 128-bit UINTMAX_MAX value |
* minus one) past the decimal point due to our conversion method. |
*/ |
switch (sizeof(UINTMAX_T)) { |
case 16: |
if (precision > 38) |
precision = 38; |
break; |
case 8: |
if (precision > 19) |
precision = 19; |
break; |
default: |
if (precision > 9) |
precision = 9; |
break; |
} |
ufvalue = (fvalue >= 0.0) ? fvalue : -fvalue; |
if (estyle) /* We want exactly one integer digit. */ |
ufvalue /= mypow10(exponent); |
if ((intpart = cast(ufvalue)) == UINTMAX_MAX) { |
*overflow = 1; |
return; |
} |
/* |
* Factor of ten with the number of digits needed for the fractional |
* part. For example, if the precision is 3, the mask will be 1000. |
*/ |
mask = (UINTMAX_T)mypow10(precision); |
/* |
* We "cheat" by converting the fractional part to integer by |
* multiplying by a factor of ten. |
*/ |
if ((fracpart = myround(mask * (ufvalue - intpart))) >= mask) { |
/* |
* For example, ufvalue = 2.99962, intpart = 2, and mask = 1000 |
* (because precision = 3). Now, myround(1000 * 0.99962) will |
* return 1000. So, the integer part must be incremented by one |
* and the fractional part must be set to zero. |
*/ |
intpart++; |
fracpart = 0; |
if (estyle && intpart == 10) { |
/* |
* The value was rounded up to ten, but we only want one |
* integer digit if using "e-style". So, the integer |
* part must be set to one and the exponent must be |
* incremented by one. |
*/ |
intpart = 1; |
exponent++; |
} |
} |
/* |
* Now that we know the real exponent, we can check whether or not to |
* use "e-style" for "%g" (and "%G") conversions. If we don't need |
* "e-style", the precision must be adjusted and the integer and |
* fractional parts must be recalculated from the original value. |
* |
* C99 says: "Let P equal the precision if nonzero, 6 if the precision |
* is omitted, or 1 if the precision is zero. Then, if a conversion |
* with style `E' would have an exponent of X: |
* |
* - if P > X >= -4, the conversion is with style `f' (or `F') and |
* precision P - (X + 1). |
* |
* - otherwise, the conversion is with style `e' (or `E') and precision |
* P - 1." (7.19.6.1, 8) |
* |
* Note that we had decremented the precision by one. |
*/ |
if (flags & PRINT_F_TYPE_G && estyle && |
precision + 1 > exponent && exponent >= -4) { |
precision -= exponent; |
estyle = 0; |
goto again; |
} |
if (estyle) { |
if (exponent < 0) { |
exponent = -exponent; |
esign = '-'; |
} else |
esign = '+'; |
/* |
* Convert the exponent. The sizeof(econvert) is 4. So, the |
* econvert buffer can hold e.g. "e+99" and "e-99". We don't |
* support an exponent which contains more than two digits. |
* Therefore, the following stores are safe. |
*/ |
epos = convert(exponent, econvert, 2, 10, 0); |
/* |
* C99 says: "The exponent always contains at least two digits, |
* and only as many more digits as necessary to represent the |
* exponent." (7.19.6.1, 8) |
*/ |
if (epos == 1) |
econvert[epos++] = '0'; |
econvert[epos++] = esign; |
econvert[epos++] = (flags & PRINT_F_UP) ? 'E' : 'e'; |
} |
/* Convert the integer part and the fractional part. */ |
ipos = convert(intpart, iconvert, sizeof(iconvert), 10, 0); |
if (fracpart != 0) /* convert() would return 1 if fracpart == 0. */ |
fpos = convert(fracpart, fconvert, sizeof(fconvert), 10, 0); |
leadfraczeros = precision - fpos; |
if (omitzeros) { |
if (fpos > 0) /* Omit trailing fractional part zeros. */ |
while (omitcount < fpos && fconvert[omitcount] == '0') |
omitcount++; |
else { /* The fractional part is zero, omit it completely. */ |
omitcount = precision; |
leadfraczeros = 0; |
} |
precision -= omitcount; |
} |
/* |
* Print a decimal point if either the fractional part is non-zero |
* and/or the "#" flag was specified. |
*/ |
if (precision > 0 || flags & PRINT_F_NUM) |
emitpoint = 1; |
if (separators) /* Get the number of group separators we'll print. */ |
separators = getnumsep(ipos); |
padlen = width /* Minimum field width. */ |
- ipos /* Number of integer digits. */ |
- epos /* Number of exponent characters. */ |
- precision /* Number of fractional digits. */ |
- separators /* Number of group separators. */ |
- (emitpoint ? 1 : 0) /* Will we print a decimal point? */ |
- ((sign != 0) ? 1 : 0); /* Will we print a sign character? */ |
if (padlen < 0) |
padlen = 0; |
/* |
* C99 says: "If the `0' and `-' flags both appear, the `0' flag is |
* ignored." (7.19.6.1, 6) |
*/ |
if (flags & PRINT_F_MINUS) /* Left justifty. */ |
padlen = -padlen; |
else if (flags & PRINT_F_ZERO && padlen > 0) { |
if (sign != 0) { /* Sign. */ |
OUTCHAR(str, *len, size, sign); |
sign = 0; |
} |
while (padlen > 0) { /* Leading zeros. */ |
OUTCHAR(str, *len, size, '0'); |
padlen--; |
} |
} |
while (padlen > 0) { /* Leading spaces. */ |
OUTCHAR(str, *len, size, ' '); |
padlen--; |
} |
if (sign != 0) /* Sign. */ |
OUTCHAR(str, *len, size, sign); |
while (ipos > 0) { /* Integer part. */ |
ipos--; |
OUTCHAR(str, *len, size, iconvert[ipos]); |
if (separators > 0 && ipos > 0 && ipos % 3 == 0) |
printsep(str, len, size); |
} |
if (emitpoint) { /* Decimal point. */ |
#if HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT |
if (lc->decimal_point != NULL && *lc->decimal_point != '\0') |
OUTCHAR(str, *len, size, *lc->decimal_point); |
else /* We'll always print some decimal point character. */ |
#endif /* HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT */ |
OUTCHAR(str, *len, size, '.'); |
} |
while (leadfraczeros > 0) { /* Leading fractional part zeros. */ |
OUTCHAR(str, *len, size, '0'); |
leadfraczeros--; |
} |
while (fpos > omitcount) { /* The remaining fractional part. */ |
fpos--; |
OUTCHAR(str, *len, size, fconvert[fpos]); |
} |
while (epos > 0) { /* Exponent. */ |
epos--; |
OUTCHAR(str, *len, size, econvert[epos]); |
} |
while (padlen < 0) { /* Trailing spaces. */ |
OUTCHAR(str, *len, size, ' '); |
padlen++; |
} |
} |
static void |
printsep(char *str, size_t *len, size_t size) |
{ |
#if HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP |
struct lconv *lc = localeconv(); |
int i; |
if (lc->thousands_sep != NULL) |
for (i = 0; lc->thousands_sep[i] != '\0'; i++) |
OUTCHAR(str, *len, size, lc->thousands_sep[i]); |
else |
#endif /* HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP */ |
OUTCHAR(str, *len, size, ','); |
} |
static int |
getnumsep(int digits) |
{ |
int separators = (digits - ((digits % 3 == 0) ? 1 : 0)) / 3; |
#if HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP |
int strln; |
struct lconv *lc = localeconv(); |
/* We support an arbitrary separator length (including zero). */ |
if (lc->thousands_sep != NULL) { |
for (strln = 0; lc->thousands_sep[strln] != '\0'; strln++) |
continue; |
separators *= strln; |
} |
#endif /* HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP */ |
return separators; |
} |
static int |
getexponent(LDOUBLE value) |
{ |
LDOUBLE tmp = (value >= 0.0) ? value : -value; |
int exponent = 0; |
/* |
* We check for 99 > exponent > -99 in order to work around possible |
* endless loops which could happen (at least) in the second loop (at |
* least) if we're called with an infinite value. However, we checked |
* for infinity before calling this function using our ISINF() macro, so |
* this might be somewhat paranoid. |
*/ |
while (tmp < 1.0 && tmp > 0.0 && --exponent > -99) |
tmp *= 10; |
while (tmp >= 10.0 && ++exponent < 99) |
tmp /= 10; |
return exponent; |
} |
static int |
convert(UINTMAX_T value, char *buf, size_t size, int base, int caps) |
{ |
const char *digits = caps ? "0123456789ABCDEF" : "0123456789abcdef"; |
size_t pos = 0; |
/* We return an unterminated buffer with the digits in reverse order. */ |
do { |
buf[pos++] = digits[value % base]; |
value /= base; |
} while (value != 0 && pos < size); |
return (int)pos; |
} |
static UINTMAX_T |
cast(LDOUBLE value) |
{ |
UINTMAX_T result; |
/* |
* We check for ">=" and not for ">" because if UINTMAX_MAX cannot be |
* represented exactly as an LDOUBLE value (but is less than LDBL_MAX), |
* it may be increased to the nearest higher representable value for the |
* comparison (cf. C99: 6.3.1.4, 2). It might then equal the LDOUBLE |
* value although converting the latter to UINTMAX_T would overflow. |
*/ |
if (value >= UINTMAX_MAX) |
return UINTMAX_MAX; |
result = (UINTMAX_T)value; |
/* |
* At least on NetBSD/sparc64 3.0.2 and 4.99.30, casting long double to |
* an integer type converts e.g. 1.9 to 2 instead of 1 (which violates |
* the standard). Sigh. |
*/ |
return (result <= value) ? result : result - 1; |
} |
static UINTMAX_T |
myround(LDOUBLE value) |
{ |
UINTMAX_T intpart = cast(value); |
return ((value -= intpart) < 0.5) ? intpart : intpart + 1; |
} |
static LDOUBLE |
mypow10(int exponent) |
{ |
LDOUBLE result = 1; |
while (exponent > 0) { |
result *= 10; |
exponent--; |
} |
while (exponent < 0) { |
result /= 10; |
exponent++; |
} |
return result; |
} |
#endif /* !HAVE_VSNPRINTF */ |
#if !HAVE_VASPRINTF |
#if NEED_MYMEMCPY |
void * |
mymemcpy(void *dst, void *src, size_t len) |
{ |
const char *from = src; |
char *to = dst; |
/* No need for optimization, we use this only to replace va_copy(3). */ |
while (len-- > 0) |
*to++ = *from++; |
return dst; |
} |
#endif /* NEED_MYMEMCPY */ |
int |
util_vasprintf(char **ret, const char *format, va_list ap) |
{ |
size_t size; |
int len; |
va_list aq; |
VA_COPY(aq, ap); |
len = vsnprintf(NULL, 0, format, aq); |
VA_END_COPY(aq); |
if (len < 0 || (*ret = malloc(size = len + 1)) == NULL) |
return -1; |
return vsnprintf(*ret, size, format, ap); |
} |
#endif /* !HAVE_VASPRINTF */ |
#if !HAVE_SNPRINTF |
#if HAVE_STDARG_H |
int |
util_snprintf(char *str, size_t size, const char *format, ...) |
#else |
int |
util_snprintf(va_alist) va_dcl |
#endif /* HAVE_STDARG_H */ |
{ |
#if !HAVE_STDARG_H |
char *str; |
size_t size; |
char *format; |
#endif /* HAVE_STDARG_H */ |
va_list ap; |
int len; |
VA_START(ap, format); |
VA_SHIFT(ap, str, char *); |
VA_SHIFT(ap, size, size_t); |
VA_SHIFT(ap, format, const char *); |
len = vsnprintf(str, size, format, ap); |
va_end(ap); |
return len; |
} |
#endif /* !HAVE_SNPRINTF */ |
#if !HAVE_ASPRINTF |
#if HAVE_STDARG_H |
int |
util_asprintf(char **ret, const char *format, ...) |
#else |
int |
util_asprintf(va_alist) va_dcl |
#endif /* HAVE_STDARG_H */ |
{ |
#if !HAVE_STDARG_H |
char **ret; |
char *format; |
#endif /* HAVE_STDARG_H */ |
va_list ap; |
int len; |
VA_START(ap, format); |
VA_SHIFT(ap, ret, char **); |
VA_SHIFT(ap, format, const char *); |
len = vasprintf(ret, format, ap); |
va_end(ap); |
return len; |
} |
#endif /* !HAVE_ASPRINTF */ |
#else /* Dummy declaration to avoid empty translation unit warnings. */ |
int main(void); |
#endif /* !HAVE_SNPRINTF || !HAVE_VSNPRINTF || !HAVE_ASPRINTF || [...] */ |
/* vim: set joinspaces textwidth=80: */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_split_prim.h |
---|
0,0 → 1,114 |
/* Originally written by Ben Skeggs for the nv50 driver*/ |
#ifndef U_SPLIT_PRIM_H |
#define U_SPLIT_PRIM_H |
#include "pipe/p_defines.h" |
#include "pipe/p_compiler.h" |
#include "util/u_debug.h" |
struct util_split_prim { |
void *priv; |
void (*emit)(void *priv, unsigned start, unsigned count); |
void (*edge)(void *priv, boolean enabled); |
unsigned mode; |
unsigned start; |
unsigned p_start; |
unsigned p_end; |
uint repeat_first:1; |
uint close_first:1; |
uint edgeflag_off:1; |
}; |
static INLINE void |
util_split_prim_init(struct util_split_prim *s, |
unsigned mode, unsigned start, unsigned count) |
{ |
if (mode == PIPE_PRIM_LINE_LOOP) { |
s->mode = PIPE_PRIM_LINE_STRIP; |
s->close_first = 1; |
} else { |
s->mode = mode; |
s->close_first = 0; |
} |
s->start = start; |
s->p_start = start; |
s->p_end = start + count; |
s->edgeflag_off = 0; |
s->repeat_first = 0; |
} |
static INLINE boolean |
util_split_prim_next(struct util_split_prim *s, unsigned max_verts) |
{ |
int repeat = 0; |
if (s->repeat_first) { |
s->emit(s->priv, s->start, 1); |
max_verts--; |
if (s->edgeflag_off) { |
s->edge(s->priv, TRUE); |
s->edgeflag_off = FALSE; |
} |
} |
if ((s->p_end - s->p_start) + s->close_first <= max_verts) { |
s->emit(s->priv, s->p_start, s->p_end - s->p_start); |
if (s->close_first) |
s->emit(s->priv, s->start, 1); |
return TRUE; |
} |
switch (s->mode) { |
case PIPE_PRIM_LINES: |
max_verts &= ~1; |
break; |
case PIPE_PRIM_LINE_STRIP: |
repeat = 1; |
break; |
case PIPE_PRIM_POLYGON: |
max_verts--; |
s->emit(s->priv, s->p_start, max_verts); |
s->edge(s->priv, FALSE); |
s->emit(s->priv, s->p_start + max_verts, 1); |
s->p_start += max_verts; |
s->repeat_first = TRUE; |
s->edgeflag_off = TRUE; |
return FALSE; |
case PIPE_PRIM_TRIANGLES: |
max_verts = max_verts - (max_verts % 3); |
break; |
case PIPE_PRIM_TRIANGLE_STRIP: |
/* to ensure winding stays correct, always split |
* on an even number of generated triangles |
*/ |
max_verts = max_verts & ~1; |
repeat = 2; |
break; |
case PIPE_PRIM_TRIANGLE_FAN: |
s->repeat_first = TRUE; |
repeat = 1; |
break; |
case PIPE_PRIM_QUADS: |
max_verts &= ~3; |
break; |
case PIPE_PRIM_QUAD_STRIP: |
max_verts &= ~1; |
repeat = 2; |
break; |
case PIPE_PRIM_POINTS: |
break; |
default: |
/* TODO: implement adjacency primitives */ |
assert(0); |
} |
s->emit (s->priv, s->p_start, max_verts); |
s->p_start += (max_verts - repeat); |
return FALSE; |
} |
#endif /* U_SPLIT_PRIM_H */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_sse.h |
---|
0,0 → 1,260 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* 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 TUNGSTEN GRAPHICS 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. |
* |
**************************************************************************/ |
/** |
* @file |
* SSE intrinsics portability header. |
* |
* Although the SSE intrinsics are support by all modern x86 and x86-64 |
* compilers, there are some intrisincs missing in some implementations |
* (especially older MSVC versions). This header abstracts that away. |
*/ |
#ifndef U_SSE_H_ |
#define U_SSE_H_ |
#include "pipe/p_config.h" |
#if defined(PIPE_ARCH_SSE) |
#include <emmintrin.h> |
/* MSVC before VC8 does not support the _mm_castxxx_yyy */ |
#if defined(_MSC_VER) && _MSC_VER < 1500 |
union __declspec(align(16)) m128_types { |
__m128 m128; |
__m128i m128i; |
__m128d m128d; |
}; |
static __inline __m128 |
_mm_castsi128_ps(__m128i a) |
{ |
union m128_types u; |
u.m128i = a; |
return u.m128; |
} |
static __inline __m128i |
_mm_castps_si128(__m128 a) |
{ |
union m128_types u; |
u.m128 = a; |
return u.m128i; |
} |
#endif /* defined(_MSC_VER) && _MSC_VER < 1500 */ |
union m128i { |
__m128i m; |
ubyte ub[16]; |
ushort us[8]; |
uint ui[4]; |
}; |
static INLINE void u_print_epi8(const char *name, __m128i r) |
{ |
union { __m128i m; ubyte ub[16]; } u; |
u.m = r; |
debug_printf("%s: " |
"%02x/" |
"%02x/" |
"%02x/" |
"%02x/" |
"%02x/" |
"%02x/" |
"%02x/" |
"%02x/" |
"%02x/" |
"%02x/" |
"%02x/" |
"%02x/" |
"%02x/" |
"%02x/" |
"%02x/" |
"%02x\n", |
name, |
u.ub[0], u.ub[1], u.ub[2], u.ub[3], |
u.ub[4], u.ub[5], u.ub[6], u.ub[7], |
u.ub[8], u.ub[9], u.ub[10], u.ub[11], |
u.ub[12], u.ub[13], u.ub[14], u.ub[15]); |
} |
static INLINE void u_print_epi16(const char *name, __m128i r) |
{ |
union { __m128i m; ushort us[8]; } u; |
u.m = r; |
debug_printf("%s: " |
"%04x/" |
"%04x/" |
"%04x/" |
"%04x/" |
"%04x/" |
"%04x/" |
"%04x/" |
"%04x\n", |
name, |
u.us[0], u.us[1], u.us[2], u.us[3], |
u.us[4], u.us[5], u.us[6], u.us[7]); |
} |
static INLINE void u_print_epi32(const char *name, __m128i r) |
{ |
union { __m128i m; uint ui[4]; } u; |
u.m = r; |
debug_printf("%s: " |
"%08x/" |
"%08x/" |
"%08x/" |
"%08x\n", |
name, |
u.ui[0], u.ui[1], u.ui[2], u.ui[3]); |
} |
static INLINE void u_print_ps(const char *name, __m128 r) |
{ |
union { __m128 m; float f[4]; } u; |
u.m = r; |
debug_printf("%s: " |
"%f/" |
"%f/" |
"%f/" |
"%f\n", |
name, |
u.f[0], u.f[1], u.f[2], u.f[3]); |
} |
#define U_DUMP_EPI32(a) u_print_epi32(#a, a) |
#define U_DUMP_EPI16(a) u_print_epi16(#a, a) |
#define U_DUMP_EPI8(a) u_print_epi8(#a, a) |
#define U_DUMP_PS(a) u_print_ps(#a, a) |
#if defined(PIPE_ARCH_SSSE3) |
#include <tmmintrin.h> |
#else /* !PIPE_ARCH_SSSE3 */ |
/** |
* Describe _mm_shuffle_epi8() with gcc extended inline assembly, for cases |
* where -mssse3 is not supported/enabled. |
* |
* MSVC will never get in here as its intrinsics support do not rely on |
* compiler command line options. |
*/ |
static __inline __m128i |
#ifdef __clang__ |
__attribute__((__always_inline__, __nodebug__)) |
#else |
__attribute__((__gnu_inline__, __always_inline__, __artificial__)) |
#endif |
_mm_shuffle_epi8(__m128i a, __m128i mask) |
{ |
__m128i result; |
__asm__("pshufb %1, %0" |
: "=x" (result) |
: "xm" (mask), "0" (a)); |
return result; |
} |
#endif /* !PIPE_ARCH_SSSE3 */ |
/* Provide an SSE2 implementation of _mm_mullo_epi32() in terms of |
* _mm_mul_epu32(). |
* |
* I suspect this works fine for us because one of our operands is |
* always positive, but not sure that this can be used for general |
* signed integer multiplication. |
* |
* This seems close enough to the speed of SSE4 and the real |
* _mm_mullo_epi32() intrinsic as to not justify adding an sse4 |
* dependency at this point. |
*/ |
static INLINE __m128i mm_mullo_epi32(const __m128i a, const __m128i b) |
{ |
__m128i a4 = _mm_srli_epi64(a, 32); /* shift by one dword */ |
__m128i b4 = _mm_srli_epi64(b, 32); /* shift by one dword */ |
__m128i ba = _mm_mul_epu32(b, a); /* multply dwords 0, 2 */ |
__m128i b4a4 = _mm_mul_epu32(b4, a4); /* multiply dwords 1, 3 */ |
/* Interleave the results, either with shuffles or (slightly |
* faster) direct bit operations: |
*/ |
#if 0 |
__m128i ba8 = _mm_shuffle_epi32(ba, 8); |
__m128i b4a48 = _mm_shuffle_epi32(b4a4, 8); |
__m128i result = _mm_unpacklo_epi32(ba8, b4a48); |
#else |
__m128i mask = _mm_setr_epi32(~0,0,~0,0); |
__m128i ba_mask = _mm_and_si128(ba, mask); |
__m128i b4a4_mask_shift = _mm_slli_epi64(b4a4, 32); |
__m128i result = _mm_or_si128(ba_mask, b4a4_mask_shift); |
#endif |
return result; |
} |
static INLINE void |
transpose4_epi32(const __m128i * restrict a, |
const __m128i * restrict b, |
const __m128i * restrict c, |
const __m128i * restrict d, |
__m128i * restrict o, |
__m128i * restrict p, |
__m128i * restrict q, |
__m128i * restrict r) |
{ |
__m128i t0 = _mm_unpacklo_epi32(*a, *b); |
__m128i t1 = _mm_unpacklo_epi32(*c, *d); |
__m128i t2 = _mm_unpackhi_epi32(*a, *b); |
__m128i t3 = _mm_unpackhi_epi32(*c, *d); |
*o = _mm_unpacklo_epi64(t0, t1); |
*p = _mm_unpackhi_epi64(t0, t1); |
*q = _mm_unpacklo_epi64(t2, t3); |
*r = _mm_unpackhi_epi64(t2, t3); |
} |
#define SCALAR_EPI32(m, i) _mm_shuffle_epi32((m), _MM_SHUFFLE(i,i,i,i)) |
#endif /* PIPE_ARCH_SSE */ |
#endif /* U_SSE_H_ */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_staging.c |
---|
0,0 → 1,132 |
/************************************************************************** |
* |
* Copyright 2010 Luca Barbieri |
* |
* 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, sublicense, 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 NONINFRINGEMENT. |
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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_staging.h" |
#include "pipe/p_context.h" |
#include "util/u_memory.h" |
#include "util/u_inlines.h" |
static void |
util_staging_resource_template(struct pipe_resource *pt, unsigned width, unsigned height, unsigned depth, struct pipe_resource *template) |
{ |
memset(template, 0, sizeof(struct pipe_resource)); |
if(pt->target != PIPE_BUFFER && depth <= 1) |
template->target = PIPE_TEXTURE_RECT; |
else |
template->target = pt->target; |
template->format = pt->format; |
template->width0 = width; |
template->height0 = height; |
template->depth0 = depth; |
template->array_size = 1; |
template->last_level = 0; |
template->nr_samples = pt->nr_samples; |
template->bind = 0; |
template->usage = PIPE_USAGE_STAGING; |
template->flags = 0; |
} |
struct util_staging_transfer * |
util_staging_transfer_init(struct pipe_context *pipe, |
struct pipe_resource *pt, |
unsigned level, |
unsigned usage, |
const struct pipe_box *box, |
boolean direct, struct util_staging_transfer *tx) |
{ |
struct pipe_screen *pscreen = pipe->screen; |
struct pipe_resource staging_resource_template; |
pipe_resource_reference(&tx->base.resource, pt); |
tx->base.level = level; |
tx->base.usage = usage; |
tx->base.box = *box; |
if (direct) |
{ |
tx->staging_resource = pt; |
return tx; |
} |
util_staging_resource_template(pt, box->width, box->height, box->depth, &staging_resource_template); |
tx->staging_resource = pscreen->resource_create(pscreen, &staging_resource_template); |
if (!tx->staging_resource) |
{ |
pipe_resource_reference(&tx->base.resource, NULL); |
FREE(tx); |
return NULL; |
} |
if (usage & PIPE_TRANSFER_READ) |
{ |
/* XXX this looks wrong dst is always the same but looping over src z? */ |
int zi; |
struct pipe_box sbox; |
sbox.x = box->x; |
sbox.y = box->y; |
sbox.z = box->z; |
sbox.width = box->width; |
sbox.height = box->height; |
sbox.depth = 1; |
for(zi = 0; zi < box->depth; ++zi) { |
sbox.z = sbox.z + zi; |
pipe->resource_copy_region(pipe, tx->staging_resource, 0, 0, 0, 0, |
tx->base.resource, level, &sbox); |
} |
} |
return tx; |
} |
void |
util_staging_transfer_destroy(struct pipe_context *pipe, struct pipe_transfer *ptx) |
{ |
struct util_staging_transfer *tx = (struct util_staging_transfer *)ptx; |
if (tx->staging_resource != tx->base.resource) |
{ |
if(tx->base.usage & PIPE_TRANSFER_WRITE) { |
/* XXX this looks wrong src is always the same but looping over dst z? */ |
int zi; |
struct pipe_box sbox; |
sbox.x = 0; |
sbox.y = 0; |
sbox.z = 0; |
sbox.width = tx->base.box.width; |
sbox.height = tx->base.box.height; |
sbox.depth = 1; |
for(zi = 0; zi < tx->base.box.depth; ++zi) |
pipe->resource_copy_region(pipe, tx->base.resource, tx->base.level, tx->base.box.x, tx->base.box.y, tx->base.box.z + zi, |
tx->staging_resource, 0, &sbox); |
} |
pipe_resource_reference(&tx->staging_resource, NULL); |
} |
pipe_resource_reference(&ptx->resource, NULL); |
FREE(ptx); |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_staging.h |
---|
0,0 → 1,63 |
/************************************************************************** |
* |
* Copyright 2010 Luca Barbieri |
* |
* 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, sublicense, 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 NONINFRINGEMENT. |
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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. |
* |
**************************************************************************/ |
/* Direct3D 10/11 has no concept of transfers. Applications instead |
* create resources with a STAGING or DYNAMIC usage, copy between them |
* and the real resource and use Map to map the STAGING/DYNAMIC resource. |
* |
* This util module allows to implement Gallium drivers as a Direct3D |
* driver would be implemented: transfers allocate a resource with |
* PIPE_USAGE_STAGING, and copy the data between it and the real resource |
* with resource_copy_region. |
*/ |
#ifndef U_STAGING_H |
#define U_STAGING_H |
#include "pipe/p_state.h" |
struct util_staging_transfer { |
struct pipe_transfer base; |
/* if direct, same as base.resource, otherwise the temporary staging resource */ |
struct pipe_resource *staging_resource; |
}; |
/* user must be stride, slice_stride and offset */ |
/* pt->usage == PIPE_USAGE_DYNAMIC || pt->usage == PIPE_USAGE_STAGING should be a good value to pass for direct */ |
/* staging resource is currently created with PIPE_USAGE_STAGING */ |
struct util_staging_transfer * |
util_staging_transfer_init(struct pipe_context *pipe, |
struct pipe_resource *pt, |
unsigned level, |
unsigned usage, |
const struct pipe_box *box, |
boolean direct, struct util_staging_transfer *tx); |
void |
util_staging_transfer_destroy(struct pipe_context *pipe, struct pipe_transfer *ptx); |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_string.h |
---|
0,0 → 1,232 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* 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 TUNGSTEN GRAPHICS 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. |
* |
**************************************************************************/ |
/** |
* @file |
* Platform independent functions for string manipulation. |
* |
* @author Jose Fonseca <jrfonseca@tungstengraphics.com> |
*/ |
#ifndef U_STRING_H_ |
#define U_STRING_H_ |
#if !defined(_MSC_VER) && !defined(XF86_LIBC_H) |
#include <stdio.h> |
#endif |
#include <stddef.h> |
#include <stdarg.h> |
#include "pipe/p_compiler.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
#ifdef _GNU_SOURCE |
#define util_strchrnul strchrnul |
#else |
static INLINE char * |
util_strchrnul(const char *s, char c) |
{ |
for (; *s && *s != c; ++s); |
return (char *)s; |
} |
#endif |
#ifdef _MSC_VER |
int util_vsnprintf(char *, size_t, const char *, va_list); |
int util_snprintf(char *str, size_t size, const char *format, ...); |
static INLINE void |
util_vsprintf(char *str, const char *format, va_list ap) |
{ |
util_vsnprintf(str, (size_t)-1, format, ap); |
} |
static INLINE void |
util_sprintf(char *str, const char *format, ...) |
{ |
va_list ap; |
va_start(ap, format); |
util_vsnprintf(str, (size_t)-1, format, ap); |
va_end(ap); |
} |
static INLINE char * |
util_strchr(const char *s, char c) |
{ |
char *p = util_strchrnul(s, c); |
return *p ? p : NULL; |
} |
static INLINE char* |
util_strncat(char *dst, const char *src, size_t n) |
{ |
char *p = dst + strlen(dst); |
const char *q = src; |
size_t i; |
for (i = 0; i < n && *q != '\0'; ++i) |
*p++ = *q++; |
*p = '\0'; |
return dst; |
} |
static INLINE int |
util_strcmp(const char *s1, const char *s2) |
{ |
unsigned char u1, u2; |
while (1) { |
u1 = (unsigned char) *s1++; |
u2 = (unsigned char) *s2++; |
if (u1 != u2) |
return u1 - u2; |
if (u1 == '\0') |
return 0; |
} |
return 0; |
} |
static INLINE int |
util_strncmp(const char *s1, const char *s2, size_t n) |
{ |
unsigned char u1, u2; |
while (n-- > 0) { |
u1 = (unsigned char) *s1++; |
u2 = (unsigned char) *s2++; |
if (u1 != u2) |
return u1 - u2; |
if (u1 == '\0') |
return 0; |
} |
return 0; |
} |
static INLINE char * |
util_strstr(const char *haystack, const char *needle) |
{ |
const char *p = haystack; |
size_t len = strlen(needle); |
for (; (p = util_strchr(p, *needle)) != 0; p++) { |
if (util_strncmp(p, needle, len) == 0) { |
return (char *)p; |
} |
} |
return NULL; |
} |
static INLINE void * |
util_memmove(void *dest, const void *src, size_t n) |
{ |
char *p = (char *)dest; |
const char *q = (const char *)src; |
if (dest < src) { |
while (n--) |
*p++ = *q++; |
} |
else |
{ |
p += n; |
q += n; |
while (n--) |
*--p = *--q; |
} |
return dest; |
} |
#else |
#define util_vsnprintf vsnprintf |
#define util_snprintf snprintf |
#define util_vsprintf vsprintf |
#define util_sprintf sprintf |
#define util_strchr strchr |
#define util_strcmp strcmp |
#define util_strncmp strncmp |
#define util_strncat strncat |
#define util_strstr strstr |
#define util_memmove memmove |
#endif |
/** |
* Printable string buffer |
*/ |
struct util_strbuf |
{ |
char *str; |
char *ptr; |
size_t left; |
}; |
static INLINE void |
util_strbuf_init(struct util_strbuf *sbuf, char *str, size_t size) |
{ |
sbuf->str = str; |
sbuf->str[0] = 0; |
sbuf->ptr = sbuf->str; |
sbuf->left = size; |
} |
static INLINE void |
util_strbuf_printf(struct util_strbuf *sbuf, const char *format, ...) |
{ |
if(sbuf->left > 1) { |
size_t written; |
va_list ap; |
va_start(ap, format); |
written = util_vsnprintf(sbuf->ptr, sbuf->left, format, ap); |
va_end(ap); |
sbuf->ptr += written; |
sbuf->left -= written; |
} |
} |
#ifdef __cplusplus |
} |
#endif |
#endif /* U_STRING_H_ */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_suballoc.c |
---|
0,0 → 1,132 |
/************************************************************************** |
* |
* Copyright 2009 VMware, Inc. |
* Copyright 2012 Marek Olšák <maraeo@gmail.com> |
* 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 THE 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. |
* |
**************************************************************************/ |
/* A simple allocator that suballocates memory from a large buffer. */ |
#include "pipe/p_defines.h" |
#include "util/u_inlines.h" |
#include "pipe/p_context.h" |
#include "util/u_memory.h" |
#include "util/u_math.h" |
#include "u_suballoc.h" |
struct u_suballocator { |
struct pipe_context *pipe; |
unsigned size; /* Size of the whole buffer, in bytes. */ |
unsigned alignment; /* Alignment of each sub-allocation. */ |
unsigned bind; /* Bitmask of PIPE_BIND_* flags. */ |
unsigned usage; /* One of PIPE_USAGE_* flags. */ |
boolean zero_buffer_memory; /* If the buffer contents should be zeroed. */ |
struct pipe_resource *buffer; /* The buffer we suballocate from. */ |
unsigned offset; /* Aligned offset pointing at the first unused byte. */ |
}; |
/** |
* Create a suballocator. |
* |
* \p zero_buffer_memory determines whether the buffer contents should be |
* cleared to 0 after the allocation. |
*/ |
struct u_suballocator * |
u_suballocator_create(struct pipe_context *pipe, unsigned size, |
unsigned alignment, unsigned bind, unsigned usage, |
boolean zero_buffer_memory) |
{ |
struct u_suballocator *allocator = CALLOC_STRUCT(u_suballocator); |
if (!allocator) |
return NULL; |
allocator->pipe = pipe; |
allocator->size = align(size, alignment); |
allocator->alignment = alignment; |
allocator->bind = bind; |
allocator->usage = usage; |
allocator->zero_buffer_memory = zero_buffer_memory; |
return allocator; |
} |
void |
u_suballocator_destroy(struct u_suballocator *allocator) |
{ |
pipe_resource_reference(&allocator->buffer, NULL); |
FREE(allocator); |
} |
void |
u_suballocator_alloc(struct u_suballocator *allocator, unsigned size, |
unsigned *out_offset, struct pipe_resource **outbuf) |
{ |
unsigned alloc_size = align(size, allocator->alignment); |
/* Don't allow allocations larger than the buffer size. */ |
if (alloc_size > allocator->size) |
goto fail; |
/* Make sure we have enough space in the buffer. */ |
if (!allocator->buffer || |
allocator->offset + alloc_size > allocator->size) { |
/* Allocate a new buffer. */ |
pipe_resource_reference(&allocator->buffer, NULL); |
allocator->offset = 0; |
allocator->buffer = |
pipe_buffer_create(allocator->pipe->screen, allocator->bind, |
allocator->usage, allocator->size); |
if (!allocator->buffer) |
goto fail; |
/* Clear the memory if needed. */ |
if (allocator->zero_buffer_memory) { |
struct pipe_transfer *transfer = NULL; |
void *ptr; |
ptr = pipe_buffer_map(allocator->pipe, allocator->buffer, |
PIPE_TRANSFER_WRITE, &transfer); |
memset(ptr, 0, allocator->size); |
pipe_buffer_unmap(allocator->pipe, transfer); |
} |
} |
assert(allocator->offset % allocator->alignment == 0); |
assert(allocator->offset < allocator->buffer->width0); |
assert(allocator->offset + alloc_size <= allocator->buffer->width0); |
/* Return the buffer. */ |
*out_offset = allocator->offset; |
pipe_resource_reference(outbuf, allocator->buffer); |
allocator->offset += alloc_size; |
return; |
fail: |
pipe_resource_reference(outbuf, NULL); |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_suballoc.h |
---|
0,0 → 1,48 |
/************************************************************************** |
* |
* Copyright 2009 VMware, Inc. |
* Copyright 2012 Marek Olšák <maraeo@gmail.com> |
* 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 THE 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. |
* |
**************************************************************************/ |
/* A simple allocator that suballocates memory from a large buffer. */ |
#ifndef U_SUBALLOC |
#define U_SUBALLOC |
struct u_suballocator; |
struct u_suballocator * |
u_suballocator_create(struct pipe_context *pipe, unsigned size, |
unsigned alignment, unsigned bind, unsigned usage, |
boolean zero_buffer_memory); |
void |
u_suballocator_destroy(struct u_suballocator *allocator); |
void |
u_suballocator_alloc(struct u_suballocator *allocator, unsigned size, |
unsigned *out_offset, struct pipe_resource **outbuf); |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_surface.c |
---|
0,0 → 1,684 |
/************************************************************************** |
* |
* Copyright 2009 VMware, Inc. 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 VMWARE 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. |
* |
**************************************************************************/ |
/** |
* @file |
* Surface utility functions. |
* |
* @author Brian Paul |
*/ |
#include "pipe/p_defines.h" |
#include "pipe/p_screen.h" |
#include "pipe/p_state.h" |
#include "util/u_format.h" |
#include "util/u_inlines.h" |
#include "util/u_rect.h" |
#include "util/u_surface.h" |
#include "util/u_pack_color.h" |
/** |
* Initialize a pipe_surface object. 'view' is considered to have |
* uninitialized contents. |
*/ |
void |
u_surface_default_template(struct pipe_surface *surf, |
const struct pipe_resource *texture) |
{ |
memset(surf, 0, sizeof(*surf)); |
surf->format = texture->format; |
} |
/** |
* Copy 2D rect from one place to another. |
* Position and sizes are in pixels. |
* src_stride may be negative to do vertical flip of pixels from source. |
*/ |
void |
util_copy_rect(ubyte * dst, |
enum pipe_format format, |
unsigned dst_stride, |
unsigned dst_x, |
unsigned dst_y, |
unsigned width, |
unsigned height, |
const ubyte * src, |
int src_stride, |
unsigned src_x, |
unsigned src_y) |
{ |
unsigned i; |
int src_stride_pos = src_stride < 0 ? -src_stride : src_stride; |
int blocksize = util_format_get_blocksize(format); |
int blockwidth = util_format_get_blockwidth(format); |
int blockheight = util_format_get_blockheight(format); |
assert(blocksize > 0); |
assert(blockwidth > 0); |
assert(blockheight > 0); |
dst_x /= blockwidth; |
dst_y /= blockheight; |
width = (width + blockwidth - 1)/blockwidth; |
height = (height + blockheight - 1)/blockheight; |
src_x /= blockwidth; |
src_y /= blockheight; |
dst += dst_x * blocksize; |
src += src_x * blocksize; |
dst += dst_y * dst_stride; |
src += src_y * src_stride_pos; |
width *= blocksize; |
if (width == dst_stride && width == src_stride) |
memcpy(dst, src, height * width); |
else { |
for (i = 0; i < height; i++) { |
memcpy(dst, src, width); |
dst += dst_stride; |
src += src_stride; |
} |
} |
} |
/** |
* Copy 3D box from one place to another. |
* Position and sizes are in pixels. |
*/ |
void |
util_copy_box(ubyte * dst, |
enum pipe_format format, |
unsigned dst_stride, unsigned dst_slice_stride, |
unsigned dst_x, unsigned dst_y, unsigned dst_z, |
unsigned width, unsigned height, unsigned depth, |
const ubyte * src, |
int src_stride, unsigned src_slice_stride, |
unsigned src_x, unsigned src_y, unsigned src_z) |
{ |
unsigned z; |
dst += dst_z * dst_slice_stride; |
src += src_z * src_slice_stride; |
for (z = 0; z < depth; ++z) { |
util_copy_rect(dst, |
format, |
dst_stride, |
dst_x, dst_y, |
width, height, |
src, |
src_stride, |
src_x, src_y); |
dst += dst_slice_stride; |
src += src_slice_stride; |
} |
} |
void |
util_fill_rect(ubyte * dst, |
enum pipe_format format, |
unsigned dst_stride, |
unsigned dst_x, |
unsigned dst_y, |
unsigned width, |
unsigned height, |
union util_color *uc) |
{ |
const struct util_format_description *desc = util_format_description(format); |
unsigned i, j; |
unsigned width_size; |
int blocksize = desc->block.bits / 8; |
int blockwidth = desc->block.width; |
int blockheight = desc->block.height; |
assert(blocksize > 0); |
assert(blockwidth > 0); |
assert(blockheight > 0); |
dst_x /= blockwidth; |
dst_y /= blockheight; |
width = (width + blockwidth - 1)/blockwidth; |
height = (height + blockheight - 1)/blockheight; |
dst += dst_x * blocksize; |
dst += dst_y * dst_stride; |
width_size = width * blocksize; |
switch (blocksize) { |
case 1: |
if(dst_stride == width_size) |
memset(dst, uc->ub, height * width_size); |
else { |
for (i = 0; i < height; i++) { |
memset(dst, uc->ub, width_size); |
dst += dst_stride; |
} |
} |
break; |
case 2: |
for (i = 0; i < height; i++) { |
uint16_t *row = (uint16_t *)dst; |
for (j = 0; j < width; j++) |
*row++ = uc->us; |
dst += dst_stride; |
} |
break; |
case 4: |
for (i = 0; i < height; i++) { |
uint32_t *row = (uint32_t *)dst; |
for (j = 0; j < width; j++) |
*row++ = uc->ui; |
dst += dst_stride; |
} |
break; |
default: |
for (i = 0; i < height; i++) { |
ubyte *row = dst; |
for (j = 0; j < width; j++) { |
memcpy(row, uc, blocksize); |
row += blocksize; |
} |
dst += dst_stride; |
} |
break; |
} |
} |
void |
util_fill_box(ubyte * dst, |
enum pipe_format format, |
unsigned stride, |
unsigned layer_stride, |
unsigned x, |
unsigned y, |
unsigned z, |
unsigned width, |
unsigned height, |
unsigned depth, |
union util_color *uc) |
{ |
unsigned layer; |
dst += z * layer_stride; |
for (layer = z; layer < depth; layer++) { |
util_fill_rect(dst, format, |
stride, |
x, y, width, height, uc); |
dst += layer_stride; |
} |
} |
/** |
* Fallback function for pipe->resource_copy_region(). |
* Note: (X,Y)=(0,0) is always the upper-left corner. |
*/ |
void |
util_resource_copy_region(struct pipe_context *pipe, |
struct pipe_resource *dst, |
unsigned dst_level, |
unsigned dst_x, unsigned dst_y, unsigned dst_z, |
struct pipe_resource *src, |
unsigned src_level, |
const struct pipe_box *src_box) |
{ |
struct pipe_transfer *src_trans, *dst_trans; |
uint8_t *dst_map; |
const uint8_t *src_map; |
enum pipe_format src_format, dst_format; |
struct pipe_box dst_box; |
assert(src && dst); |
if (!src || !dst) |
return; |
assert((src->target == PIPE_BUFFER && dst->target == PIPE_BUFFER) || |
(src->target != PIPE_BUFFER && dst->target != PIPE_BUFFER)); |
src_format = src->format; |
dst_format = dst->format; |
assert(util_format_get_blocksize(dst_format) == util_format_get_blocksize(src_format)); |
assert(util_format_get_blockwidth(dst_format) == util_format_get_blockwidth(src_format)); |
assert(util_format_get_blockheight(dst_format) == util_format_get_blockheight(src_format)); |
src_map = pipe->transfer_map(pipe, |
src, |
src_level, |
PIPE_TRANSFER_READ, |
src_box, &src_trans); |
assert(src_map); |
if (!src_map) { |
goto no_src_map; |
} |
dst_box.x = dst_x; |
dst_box.y = dst_y; |
dst_box.z = dst_z; |
dst_box.width = src_box->width; |
dst_box.height = src_box->height; |
dst_box.depth = src_box->depth; |
dst_map = pipe->transfer_map(pipe, |
dst, |
dst_level, |
PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD_RANGE, |
&dst_box, &dst_trans); |
assert(dst_map); |
if (!dst_map) { |
goto no_dst_map; |
} |
if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) { |
assert(src_box->height == 1); |
assert(src_box->depth == 1); |
memcpy(dst_map, src_map, src_box->width); |
} else { |
util_copy_box(dst_map, |
dst_format, |
dst_trans->stride, dst_trans->layer_stride, |
0, 0, 0, |
src_box->width, src_box->height, src_box->depth, |
src_map, |
src_trans->stride, src_trans->layer_stride, |
0, 0, 0); |
} |
pipe->transfer_unmap(pipe, dst_trans); |
no_dst_map: |
pipe->transfer_unmap(pipe, src_trans); |
no_src_map: |
; |
} |
#define UBYTE_TO_USHORT(B) ((B) | ((B) << 8)) |
/** |
* Fallback for pipe->clear_render_target() function. |
* XXX this looks too hackish to be really useful. |
* cpp > 4 looks like a gross hack at best... |
* Plus can't use these transfer fallbacks when clearing |
* multisampled surfaces for instance. |
* Clears all bound layers. |
*/ |
void |
util_clear_render_target(struct pipe_context *pipe, |
struct pipe_surface *dst, |
const union pipe_color_union *color, |
unsigned dstx, unsigned dsty, |
unsigned width, unsigned height) |
{ |
struct pipe_transfer *dst_trans; |
ubyte *dst_map; |
union util_color uc; |
unsigned max_layer; |
assert(dst->texture); |
if (!dst->texture) |
return; |
if (dst->texture->target == PIPE_BUFFER) { |
/* |
* The fill naturally works on the surface format, however |
* the transfer uses resource format which is just bytes for buffers. |
*/ |
unsigned dx, w; |
unsigned pixstride = util_format_get_blocksize(dst->format); |
dx = (dst->u.buf.first_element + dstx) * pixstride; |
w = width * pixstride; |
max_layer = 0; |
dst_map = pipe_transfer_map(pipe, |
dst->texture, |
0, 0, |
PIPE_TRANSFER_WRITE, |
dx, 0, w, 1, |
&dst_trans); |
} |
else { |
max_layer = dst->u.tex.last_layer - dst->u.tex.first_layer; |
dst_map = pipe_transfer_map_3d(pipe, |
dst->texture, |
dst->u.tex.level, |
PIPE_TRANSFER_WRITE, |
dstx, dsty, dst->u.tex.first_layer, |
width, height, max_layer + 1, &dst_trans); |
} |
assert(dst_map); |
if (dst_map) { |
enum pipe_format format = dst->format; |
assert(dst_trans->stride > 0); |
if (util_format_is_pure_integer(format)) { |
/* |
* We expect int/uint clear values here, though some APIs |
* might disagree (but in any case util_pack_color() |
* couldn't handle it)... |
*/ |
if (util_format_is_pure_sint(format)) { |
util_format_write_4i(format, color->i, 0, &uc, 0, 0, 0, 1, 1); |
} |
else { |
assert(util_format_is_pure_uint(format)); |
util_format_write_4ui(format, color->ui, 0, &uc, 0, 0, 0, 1, 1); |
} |
} |
else { |
util_pack_color(color->f, dst->format, &uc); |
} |
util_fill_box(dst_map, dst->format, |
dst_trans->stride, dst_trans->layer_stride, |
0, 0, 0, width, height, max_layer + 1, &uc); |
pipe->transfer_unmap(pipe, dst_trans); |
} |
} |
/** |
* Fallback for pipe->clear_stencil() function. |
* sw fallback doesn't look terribly useful here. |
* Plus can't use these transfer fallbacks when clearing |
* multisampled surfaces for instance. |
* Clears all bound layers. |
*/ |
void |
util_clear_depth_stencil(struct pipe_context *pipe, |
struct pipe_surface *dst, |
unsigned clear_flags, |
double depth, |
unsigned stencil, |
unsigned dstx, unsigned dsty, |
unsigned width, unsigned height) |
{ |
enum pipe_format format = dst->format; |
struct pipe_transfer *dst_trans; |
ubyte *dst_map; |
boolean need_rmw = FALSE; |
unsigned max_layer, layer; |
if ((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) && |
((clear_flags & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL) && |
util_format_is_depth_and_stencil(format)) |
need_rmw = TRUE; |
assert(dst->texture); |
if (!dst->texture) |
return; |
max_layer = dst->u.tex.last_layer - dst->u.tex.first_layer; |
dst_map = pipe_transfer_map_3d(pipe, |
dst->texture, |
dst->u.tex.level, |
(need_rmw ? PIPE_TRANSFER_READ_WRITE : |
PIPE_TRANSFER_WRITE), |
dstx, dsty, dst->u.tex.first_layer, |
width, height, max_layer + 1, &dst_trans); |
assert(dst_map); |
if (dst_map) { |
unsigned dst_stride = dst_trans->stride; |
uint64_t zstencil = util_pack64_z_stencil(format, depth, stencil); |
ubyte *dst_layer = dst_map; |
unsigned i, j; |
assert(dst_trans->stride > 0); |
for (layer = 0; layer <= max_layer; layer++) { |
dst_map = dst_layer; |
switch (util_format_get_blocksize(format)) { |
case 1: |
assert(format == PIPE_FORMAT_S8_UINT); |
if(dst_stride == width) |
memset(dst_map, (uint8_t) zstencil, height * width); |
else { |
for (i = 0; i < height; i++) { |
memset(dst_map, (uint8_t) zstencil, width); |
dst_map += dst_stride; |
} |
} |
break; |
case 2: |
assert(format == PIPE_FORMAT_Z16_UNORM); |
for (i = 0; i < height; i++) { |
uint16_t *row = (uint16_t *)dst_map; |
for (j = 0; j < width; j++) |
*row++ = (uint16_t) zstencil; |
dst_map += dst_stride; |
} |
break; |
case 4: |
if (!need_rmw) { |
for (i = 0; i < height; i++) { |
uint32_t *row = (uint32_t *)dst_map; |
for (j = 0; j < width; j++) |
*row++ = (uint32_t) zstencil; |
dst_map += dst_stride; |
} |
} |
else { |
uint32_t dst_mask; |
if (format == PIPE_FORMAT_Z24_UNORM_S8_UINT) |
dst_mask = 0x00ffffff; |
else { |
assert(format == PIPE_FORMAT_S8_UINT_Z24_UNORM); |
dst_mask = 0xffffff00; |
} |
if (clear_flags & PIPE_CLEAR_DEPTH) |
dst_mask = ~dst_mask; |
for (i = 0; i < height; i++) { |
uint32_t *row = (uint32_t *)dst_map; |
for (j = 0; j < width; j++) { |
uint32_t tmp = *row & dst_mask; |
*row++ = tmp | ((uint32_t) zstencil & ~dst_mask); |
} |
dst_map += dst_stride; |
} |
} |
break; |
case 8: |
if (!need_rmw) { |
for (i = 0; i < height; i++) { |
uint64_t *row = (uint64_t *)dst_map; |
for (j = 0; j < width; j++) |
*row++ = zstencil; |
dst_map += dst_stride; |
} |
} |
else { |
uint64_t src_mask; |
if (clear_flags & PIPE_CLEAR_DEPTH) |
src_mask = 0x00000000ffffffffull; |
else |
src_mask = 0x000000ff00000000ull; |
for (i = 0; i < height; i++) { |
uint64_t *row = (uint64_t *)dst_map; |
for (j = 0; j < width; j++) { |
uint64_t tmp = *row & ~src_mask; |
*row++ = tmp | (zstencil & src_mask); |
} |
dst_map += dst_stride; |
} |
} |
break; |
default: |
assert(0); |
break; |
} |
dst_layer += dst_trans->layer_stride; |
} |
pipe->transfer_unmap(pipe, dst_trans); |
} |
} |
/* Return if the box is totally inside the resource. |
*/ |
static boolean |
is_box_inside_resource(const struct pipe_resource *res, |
const struct pipe_box *box, |
unsigned level) |
{ |
unsigned width = 1, height = 1, depth = 1; |
switch (res->target) { |
case PIPE_BUFFER: |
width = res->width0; |
height = 1; |
depth = 1; |
break; |
case PIPE_TEXTURE_1D: |
width = u_minify(res->width0, level); |
height = 1; |
depth = 1; |
break; |
case PIPE_TEXTURE_2D: |
case PIPE_TEXTURE_RECT: |
width = u_minify(res->width0, level); |
height = u_minify(res->height0, level); |
depth = 1; |
break; |
case PIPE_TEXTURE_3D: |
width = u_minify(res->width0, level); |
height = u_minify(res->height0, level); |
depth = u_minify(res->depth0, level); |
break; |
case PIPE_TEXTURE_CUBE: |
width = u_minify(res->width0, level); |
height = u_minify(res->height0, level); |
depth = 6; |
break; |
case PIPE_TEXTURE_1D_ARRAY: |
width = u_minify(res->width0, level); |
height = 1; |
depth = res->array_size; |
break; |
case PIPE_TEXTURE_2D_ARRAY: |
width = u_minify(res->width0, level); |
height = u_minify(res->height0, level); |
depth = res->array_size; |
break; |
case PIPE_TEXTURE_CUBE_ARRAY: |
width = u_minify(res->width0, level); |
height = u_minify(res->height0, level); |
depth = res->array_size; |
assert(res->array_size % 6 == 0); |
break; |
case PIPE_MAX_TEXTURE_TYPES:; |
} |
return box->x >= 0 && |
box->x + box->width <= (int) width && |
box->y >= 0 && |
box->y + box->height <= (int) height && |
box->z >= 0 && |
box->z + box->depth <= (int) depth; |
} |
static unsigned |
get_sample_count(const struct pipe_resource *res) |
{ |
return res->nr_samples ? res->nr_samples : 1; |
} |
/** |
* Try to do a blit using resource_copy_region. The function calls |
* resource_copy_region if the blit description is compatible with it. |
* |
* It returns TRUE if the blit was done using resource_copy_region. |
* |
* It returns FALSE otherwise and the caller must fall back to a more generic |
* codepath for the blit operation. (e.g. by using u_blitter) |
*/ |
boolean |
util_try_blit_via_copy_region(struct pipe_context *ctx, |
const struct pipe_blit_info *blit) |
{ |
unsigned mask = util_format_get_mask(blit->dst.format); |
/* No format conversions. */ |
if (blit->src.resource->format != blit->src.format || |
blit->dst.resource->format != blit->dst.format || |
!util_is_format_compatible( |
util_format_description(blit->src.resource->format), |
util_format_description(blit->dst.resource->format))) { |
return FALSE; |
} |
/* No masks, no filtering, no scissor. */ |
if ((blit->mask & mask) != mask || |
blit->filter != PIPE_TEX_FILTER_NEAREST || |
blit->scissor_enable) { |
return FALSE; |
} |
/* No flipping. */ |
if (blit->src.box.width < 0 || |
blit->src.box.height < 0 || |
blit->src.box.depth < 0) { |
return FALSE; |
} |
/* No scaling. */ |
if (blit->src.box.width != blit->dst.box.width || |
blit->src.box.height != blit->dst.box.height || |
blit->src.box.depth != blit->dst.box.depth) { |
return FALSE; |
} |
/* No out-of-bounds access. */ |
if (!is_box_inside_resource(blit->src.resource, &blit->src.box, |
blit->src.level) || |
!is_box_inside_resource(blit->dst.resource, &blit->dst.box, |
blit->dst.level)) { |
return FALSE; |
} |
/* Sample counts must match. */ |
if (get_sample_count(blit->src.resource) != |
get_sample_count(blit->dst.resource)) { |
return FALSE; |
} |
ctx->resource_copy_region(ctx, blit->dst.resource, blit->dst.level, |
blit->dst.box.x, blit->dst.box.y, blit->dst.box.z, |
blit->src.resource, blit->src.level, |
&blit->src.box); |
return TRUE; |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_surface.h |
---|
0,0 → 1,111 |
/************************************************************************** |
* |
* Copyright 2009 VMware, Inc. 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 VMWARE 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_SURFACE_H |
#define U_SURFACE_H |
#include "pipe/p_compiler.h" |
#include "pipe/p_state.h" |
#include "util/u_pack_color.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
extern void |
u_surface_default_template(struct pipe_surface *view, |
const struct pipe_resource *texture); |
extern void |
util_copy_rect(ubyte * dst, enum pipe_format format, |
unsigned dst_stride, unsigned dst_x, unsigned dst_y, |
unsigned width, unsigned height, const ubyte * src, |
int src_stride, unsigned src_x, unsigned src_y); |
extern void |
util_copy_box(ubyte * dst, |
enum pipe_format format, |
unsigned dst_stride, unsigned dst_slice_stride, |
unsigned dst_x, unsigned dst_y, unsigned dst_z, |
unsigned width, unsigned height, unsigned depth, |
const ubyte * src, |
int src_stride, unsigned src_slice_stride, |
unsigned src_x, unsigned src_y, unsigned src_z); |
extern void |
util_fill_rect(ubyte * dst, enum pipe_format format, |
unsigned dst_stride, unsigned dst_x, unsigned dst_y, |
unsigned width, unsigned height, union util_color *uc); |
extern void |
util_fill_box(ubyte * dst, enum pipe_format format, |
unsigned stride, unsigned layer_stride, |
unsigned x, unsigned y, unsigned z, |
unsigned width, unsigned height, unsigned depth, |
union util_color *uc); |
extern void |
util_resource_copy_region(struct pipe_context *pipe, |
struct pipe_resource *dst, |
unsigned dst_level, |
unsigned dst_x, unsigned dst_y, unsigned dst_z, |
struct pipe_resource *src, |
unsigned src_level, |
const struct pipe_box *src_box); |
extern void |
util_clear_render_target(struct pipe_context *pipe, |
struct pipe_surface *dst, |
const union pipe_color_union *color, |
unsigned dstx, unsigned dsty, |
unsigned width, unsigned height); |
extern void |
util_clear_depth_stencil(struct pipe_context *pipe, |
struct pipe_surface *dst, |
unsigned clear_flags, |
double depth, |
unsigned stencil, |
unsigned dstx, unsigned dsty, |
unsigned width, unsigned height); |
extern boolean |
util_try_blit_via_copy_region(struct pipe_context *ctx, |
const struct pipe_blit_info *blit); |
#ifdef __cplusplus |
} |
#endif |
#endif /* U_SURFACE_H */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_surfaces.c |
---|
0,0 → 1,124 |
/************************************************************************** |
* |
* Copyright 2010 Luca Barbieri |
* |
* 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, sublicense, 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 NONINFRINGEMENT. |
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "u_surfaces.h" |
#include "util/u_hash_table.h" |
#include "util/u_inlines.h" |
#include "util/u_memory.h" |
boolean |
util_surfaces_do_get(struct util_surfaces *us, unsigned surface_struct_size, |
struct pipe_context *ctx, struct pipe_resource *pt, |
unsigned level, unsigned layer, |
struct pipe_surface **res) |
{ |
struct pipe_surface *ps; |
if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE) |
{ /* or 2D array */ |
if(!us->u.hash) |
us->u.hash = cso_hash_create(); |
ps = cso_hash_iter_data(cso_hash_find(us->u.hash, (layer << 8) | level)); |
} |
else |
{ |
if(!us->u.array) |
us->u.array = CALLOC(pt->last_level + 1, sizeof(struct pipe_surface *)); |
ps = us->u.array[level]; |
} |
if(ps && ps->context == ctx) |
{ |
p_atomic_inc(&ps->reference.count); |
*res = ps; |
return FALSE; |
} |
ps = (struct pipe_surface *)CALLOC(1, surface_struct_size); |
if(!ps) |
{ |
*res = NULL; |
return FALSE; |
} |
pipe_surface_init(ctx, ps, pt, level, layer); |
if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE) |
cso_hash_insert(us->u.hash, (layer << 8) | level, ps); |
else |
us->u.array[level] = ps; |
*res = ps; |
return TRUE; |
} |
void |
util_surfaces_do_detach(struct util_surfaces *us, struct pipe_surface *ps) |
{ |
struct pipe_resource *pt = ps->texture; |
if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE) |
{ /* or 2D array */ |
cso_hash_erase(us->u.hash, cso_hash_find(us->u.hash, (ps->u.tex.first_layer << 8) | ps->u.tex.level)); |
} |
else |
us->u.array[ps->u.tex.level] = 0; |
} |
void |
util_surfaces_destroy(struct util_surfaces *us, struct pipe_resource *pt, void (*destroy_surface) (struct pipe_surface *)) |
{ |
if(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE) |
{ /* or 2D array */ |
if(us->u.hash) |
{ |
struct cso_hash_iter iter; |
iter = cso_hash_first_node(us->u.hash); |
while (!cso_hash_iter_is_null(iter)) { |
destroy_surface(cso_hash_iter_data(iter)); |
iter = cso_hash_iter_next(iter); |
} |
cso_hash_delete(us->u.hash); |
us->u.hash = NULL; |
} |
} |
else |
{ |
if(us->u.array) |
{ |
unsigned i; |
for(i = 0; i <= pt->last_level; ++i) |
{ |
struct pipe_surface *ps = us->u.array[i]; |
if(ps) |
destroy_surface(ps); |
} |
FREE(us->u.array); |
us->u.array = NULL; |
} |
} |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_surfaces.h |
---|
0,0 → 1,101 |
/************************************************************************** |
* |
* Copyright 2010 Luca Barbieri |
* |
* 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, sublicense, 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 NONINFRINGEMENT. |
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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_SURFACES_H_ |
#define U_SURFACES_H_ |
#include "pipe/p_compiler.h" |
#include "pipe/p_state.h" |
#include "util/u_atomic.h" |
#include "cso_cache/cso_hash.h" |
struct util_surfaces |
{ |
union |
{ |
struct cso_hash *hash; |
struct pipe_surface **array; |
void* pv; |
} u; |
}; |
/* Return value indicates if the pipe surface result is new */ |
boolean |
util_surfaces_do_get(struct util_surfaces *us, unsigned surface_struct_size, |
struct pipe_context *ctx, struct pipe_resource *pt, |
unsigned level, unsigned layer, |
struct pipe_surface **res); |
/* fast inline path for the very common case */ |
static INLINE boolean |
util_surfaces_get(struct util_surfaces *us, unsigned surface_struct_size, |
struct pipe_context *ctx, struct pipe_resource *pt, |
unsigned level, unsigned layer, |
struct pipe_surface **res) |
{ |
if(likely((pt->target == PIPE_TEXTURE_2D || pt->target == PIPE_TEXTURE_RECT) && us->u.array)) |
{ |
struct pipe_surface *ps = us->u.array[level]; |
if(ps && ps->context == ctx) |
{ |
p_atomic_inc(&ps->reference.count); |
*res = ps; |
return FALSE; |
} |
} |
return util_surfaces_do_get(us, surface_struct_size, ctx, pt, level, layer, res); |
} |
static INLINE struct pipe_surface * |
util_surfaces_peek(struct util_surfaces *us, struct pipe_resource *pt, unsigned level, unsigned layer) |
{ |
if(!us->u.pv) |
return 0; |
if(unlikely(pt->target == PIPE_TEXTURE_3D || pt->target == PIPE_TEXTURE_CUBE)) |
return cso_hash_iter_data(cso_hash_find(us->u.hash, (layer << 8) | level)); |
else |
return us->u.array[level]; |
} |
void util_surfaces_do_detach(struct util_surfaces *us, struct pipe_surface *ps); |
static INLINE void |
util_surfaces_detach(struct util_surfaces *us, struct pipe_surface *ps) |
{ |
if(likely(ps->texture->target == PIPE_TEXTURE_2D || ps->texture->target == PIPE_TEXTURE_RECT)) |
{ |
us->u.array[ps->u.tex.level] = 0; |
return; |
} |
util_surfaces_do_detach(us, ps); |
} |
void util_surfaces_destroy(struct util_surfaces *us, struct pipe_resource *pt, void (*destroy_surface) (struct pipe_surface *)); |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_texture.c |
---|
0,0 → 1,103 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* All Rights Reserved. |
* Copyright 2008 VMware, Inc. All rights reserved. |
* Copyright 2009 Marek Olšák <maraeo@gmail.com> |
* |
* 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 TUNGSTEN GRAPHICS 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. |
* |
**************************************************************************/ |
/** |
* @file |
* Texture mapping utility functions. |
* |
* @author Brian Paul |
* Marek Olšák |
*/ |
#include "pipe/p_defines.h" |
#include "util/u_debug.h" |
#include "util/u_texture.h" |
void util_map_texcoords2d_onto_cubemap(unsigned face, |
const float *in_st, unsigned in_stride, |
float *out_str, unsigned out_stride) |
{ |
int i; |
float rx, ry, rz; |
/* loop over quad verts */ |
for (i = 0; i < 4; i++) { |
/* Compute sc = +/-scale and tc = +/-scale. |
* Not +/-1 to avoid cube face selection ambiguity near the edges, |
* though that can still sometimes happen with this scale factor... |
*/ |
const float scale = 0.9999f; |
const float sc = (2 * in_st[0] - 1) * scale; |
const float tc = (2 * in_st[1] - 1) * scale; |
switch (face) { |
case PIPE_TEX_FACE_POS_X: |
rx = 1; |
ry = -tc; |
rz = -sc; |
break; |
case PIPE_TEX_FACE_NEG_X: |
rx = -1; |
ry = -tc; |
rz = sc; |
break; |
case PIPE_TEX_FACE_POS_Y: |
rx = sc; |
ry = 1; |
rz = tc; |
break; |
case PIPE_TEX_FACE_NEG_Y: |
rx = sc; |
ry = -1; |
rz = -tc; |
break; |
case PIPE_TEX_FACE_POS_Z: |
rx = sc; |
ry = -tc; |
rz = 1; |
break; |
case PIPE_TEX_FACE_NEG_Z: |
rx = -sc; |
ry = -tc; |
rz = -1; |
break; |
default: |
rx = ry = rz = 0; |
assert(0); |
} |
out_str[0] = rx; /*s*/ |
out_str[1] = ry; /*t*/ |
out_str[2] = rz; /*r*/ |
in_st += in_stride; |
out_str += out_stride; |
} |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_texture.h |
---|
0,0 → 1,54 |
/************************************************************************** |
* |
* Copyright 2009 Marek Olšák <maraeo@gmail.com> |
* |
* 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 TUNGSTEN GRAPHICS 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_TEXTURE_H |
#define U_TEXTURE_H |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* Convert 2D texture coordinates of 4 vertices into cubemap coordinates |
* in the given face. |
* Coordinates must be in the range [0,1]. |
* |
* \param face Cubemap face. |
* \param in_st 4 pairs of 2D texture coordinates to convert. |
* \param in_stride Stride of in_st in floats. |
* \param out_str STR cubemap texture coordinates to compute. |
* \param out_stride Stride of out_str in floats. |
*/ |
void util_map_texcoords2d_onto_cubemap(unsigned face, |
const float *in_st, unsigned in_stride, |
float *out_str, unsigned out_stride); |
#ifdef __cplusplus |
} |
#endif |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_tile.c |
---|
0,0 → 1,895 |
/************************************************************************** |
* |
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. |
* 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 TUNGSTEN GRAPHICS 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. |
* |
**************************************************************************/ |
/** |
* RGBA/float tile get/put functions. |
* Usable both by drivers and state trackers. |
*/ |
#include "pipe/p_defines.h" |
#include "util/u_inlines.h" |
#include "util/u_format.h" |
#include "util/u_math.h" |
#include "util/u_memory.h" |
#include "util/u_rect.h" |
#include "util/u_tile.h" |
/** |
* Move raw block of pixels from transfer object to user memory. |
*/ |
void |
pipe_get_tile_raw(struct pipe_transfer *pt, |
const void *src, |
uint x, uint y, uint w, uint h, |
void *dst, int dst_stride) |
{ |
if (dst_stride == 0) |
dst_stride = util_format_get_stride(pt->resource->format, w); |
if (u_clip_tile(x, y, &w, &h, &pt->box)) |
return; |
util_copy_rect(dst, pt->resource->format, dst_stride, 0, 0, w, h, src, pt->stride, x, y); |
} |
/** |
* Move raw block of pixels from user memory to transfer object. |
*/ |
void |
pipe_put_tile_raw(struct pipe_transfer *pt, |
void *dst, |
uint x, uint y, uint w, uint h, |
const void *src, int src_stride) |
{ |
enum pipe_format format = pt->resource->format; |
if (src_stride == 0) |
src_stride = util_format_get_stride(format, w); |
if (u_clip_tile(x, y, &w, &h, &pt->box)) |
return; |
util_copy_rect(dst, format, pt->stride, x, y, w, h, src, src_stride, 0, 0); |
} |
/** Convert short in [-32768,32767] to GLfloat in [-1.0,1.0] */ |
#define SHORT_TO_FLOAT(S) ((2.0F * (S) + 1.0F) * (1.0F/65535.0F)) |
#define UNCLAMPED_FLOAT_TO_SHORT(us, f) \ |
us = ( (short) ( CLAMP((f), -1.0, 1.0) * 32767.0F) ) |
/*** PIPE_FORMAT_Z16_UNORM ***/ |
/** |
* Return each Z value as four floats in [0,1]. |
*/ |
static void |
z16_get_tile_rgba(const ushort *src, |
unsigned w, unsigned h, |
float *p, |
unsigned dst_stride) |
{ |
const float scale = 1.0f / 65535.0f; |
unsigned i, j; |
for (i = 0; i < h; i++) { |
float *pRow = p; |
for (j = 0; j < w; j++, pRow += 4) { |
pRow[0] = |
pRow[1] = |
pRow[2] = |
pRow[3] = *src++ * scale; |
} |
p += dst_stride; |
} |
} |
/*** PIPE_FORMAT_Z32_UNORM ***/ |
/** |
* Return each Z value as four floats in [0,1]. |
*/ |
static void |
z32_get_tile_rgba(const unsigned *src, |
unsigned w, unsigned h, |
float *p, |
unsigned dst_stride) |
{ |
const double scale = 1.0 / (double) 0xffffffff; |
unsigned i, j; |
for (i = 0; i < h; i++) { |
float *pRow = p; |
for (j = 0; j < w; j++, pRow += 4) { |
pRow[0] = |
pRow[1] = |
pRow[2] = |
pRow[3] = (float) (*src++ * scale); |
} |
p += dst_stride; |
} |
} |
/*** PIPE_FORMAT_Z24_UNORM_S8_UINT ***/ |
/** |
* Return Z component as four float in [0,1]. Stencil part ignored. |
*/ |
static void |
s8z24_get_tile_rgba(const unsigned *src, |
unsigned w, unsigned h, |
float *p, |
unsigned dst_stride) |
{ |
const double scale = 1.0 / ((1 << 24) - 1); |
unsigned i, j; |
for (i = 0; i < h; i++) { |
float *pRow = p; |
for (j = 0; j < w; j++, pRow += 4) { |
pRow[0] = |
pRow[1] = |
pRow[2] = |
pRow[3] = (float) (scale * (*src++ & 0xffffff)); |
} |
p += dst_stride; |
} |
} |
/*** PIPE_FORMAT_S8_UINT_Z24_UNORM ***/ |
/** |
* Return Z component as four float in [0,1]. Stencil part ignored. |
*/ |
static void |
z24s8_get_tile_rgba(const unsigned *src, |
unsigned w, unsigned h, |
float *p, |
unsigned dst_stride) |
{ |
const double scale = 1.0 / ((1 << 24) - 1); |
unsigned i, j; |
for (i = 0; i < h; i++) { |
float *pRow = p; |
for (j = 0; j < w; j++, pRow += 4) { |
pRow[0] = |
pRow[1] = |
pRow[2] = |
pRow[3] = (float) (scale * (*src++ >> 8)); |
} |
p += dst_stride; |
} |
} |
/*** PIPE_FORMAT_S8X24_UINT ***/ |
/** |
* Return S component as four uint32_t in [0..255]. Z part ignored. |
*/ |
static void |
s8x24_get_tile_rgba(const unsigned *src, |
unsigned w, unsigned h, |
float *p, |
unsigned dst_stride) |
{ |
unsigned i, j; |
for (i = 0; i < h; i++) { |
float *pRow = p; |
for (j = 0; j < w; j++, pRow += 4) { |
pRow[0] = |
pRow[1] = |
pRow[2] = |
pRow[3] = (float)((*src++ >> 24) & 0xff); |
} |
p += dst_stride; |
} |
} |
/*** PIPE_FORMAT_X24S8_UINT ***/ |
/** |
* Return S component as four uint32_t in [0..255]. Z part ignored. |
*/ |
static void |
x24s8_get_tile_rgba(const unsigned *src, |
unsigned w, unsigned h, |
float *p, |
unsigned dst_stride) |
{ |
unsigned i, j; |
for (i = 0; i < h; i++) { |
float *pRow = p; |
for (j = 0; j < w; j++, pRow += 4) { |
pRow[0] = |
pRow[1] = |
pRow[2] = |
pRow[3] = (float)(*src++ & 0xff); |
} |
p += dst_stride; |
} |
} |
/** |
* Return S component as four uint32_t in [0..255]. Z part ignored. |
*/ |
static void |
s8_get_tile_rgba(const unsigned char *src, |
unsigned w, unsigned h, |
float *p, |
unsigned dst_stride) |
{ |
unsigned i, j; |
for (i = 0; i < h; i++) { |
float *pRow = p; |
for (j = 0; j < w; j++, pRow += 4) { |
pRow[0] = |
pRow[1] = |
pRow[2] = |
pRow[3] = (float)(*src++ & 0xff); |
} |
p += dst_stride; |
} |
} |
/*** PIPE_FORMAT_Z32_FLOAT ***/ |
/** |
* Return each Z value as four floats in [0,1]. |
*/ |
static void |
z32f_get_tile_rgba(const float *src, |
unsigned w, unsigned h, |
float *p, |
unsigned dst_stride) |
{ |
unsigned i, j; |
for (i = 0; i < h; i++) { |
float *pRow = p; |
for (j = 0; j < w; j++, pRow += 4) { |
pRow[0] = |
pRow[1] = |
pRow[2] = |
pRow[3] = *src++; |
} |
p += dst_stride; |
} |
} |
/*** PIPE_FORMAT_Z32_FLOAT_S8X24_UINT ***/ |
/** |
* Return each Z value as four floats in [0,1]. |
*/ |
static void |
z32f_x24s8_get_tile_rgba(const float *src, |
unsigned w, unsigned h, |
float *p, |
unsigned dst_stride) |
{ |
unsigned i, j; |
for (i = 0; i < h; i++) { |
float *pRow = p; |
for (j = 0; j < w; j++, pRow += 4) { |
pRow[0] = |
pRow[1] = |
pRow[2] = |
pRow[3] = *src; |
src += 2; |
} |
p += dst_stride; |
} |
} |
/*** PIPE_FORMAT_X32_S8X24_UINT ***/ |
/** |
* Return S component as four uint32_t in [0..255]. Z part ignored. |
*/ |
static void |
x32_s8_get_tile_rgba(const unsigned *src, |
unsigned w, unsigned h, |
float *p, |
unsigned dst_stride) |
{ |
unsigned i, j; |
for (i = 0; i < h; i++) { |
float *pRow = p; |
for (j = 0; j < w; j++, pRow += 4) { |
src++; |
pRow[0] = |
pRow[1] = |
pRow[2] = |
pRow[3] = (float)(*src++ & 0xff); |
} |
p += dst_stride; |
} |
} |
void |
pipe_tile_raw_to_rgba(enum pipe_format format, |
const void *src, |
uint w, uint h, |
float *dst, unsigned dst_stride) |
{ |
switch (format) { |
case PIPE_FORMAT_Z16_UNORM: |
z16_get_tile_rgba((ushort *) src, w, h, dst, dst_stride); |
break; |
case PIPE_FORMAT_Z32_UNORM: |
z32_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); |
break; |
case PIPE_FORMAT_Z24_UNORM_S8_UINT: |
case PIPE_FORMAT_Z24X8_UNORM: |
s8z24_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); |
break; |
case PIPE_FORMAT_S8_UINT: |
s8_get_tile_rgba((unsigned char *) src, w, h, dst, dst_stride); |
break; |
case PIPE_FORMAT_X24S8_UINT: |
s8x24_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); |
break; |
case PIPE_FORMAT_S8_UINT_Z24_UNORM: |
case PIPE_FORMAT_X8Z24_UNORM: |
z24s8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); |
break; |
case PIPE_FORMAT_S8X24_UINT: |
x24s8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); |
break; |
case PIPE_FORMAT_Z32_FLOAT: |
z32f_get_tile_rgba((float *) src, w, h, dst, dst_stride); |
break; |
case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: |
z32f_x24s8_get_tile_rgba((float *) src, w, h, dst, dst_stride); |
break; |
case PIPE_FORMAT_X32_S8X24_UINT: |
x32_s8_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride); |
break; |
default: |
util_format_read_4f(format, |
dst, dst_stride * sizeof(float), |
src, util_format_get_stride(format, w), |
0, 0, w, h); |
} |
} |
void |
pipe_tile_raw_to_unsigned(enum pipe_format format, |
const void *src, |
uint w, uint h, |
unsigned *dst, unsigned dst_stride) |
{ |
util_format_read_4ui(format, |
dst, dst_stride * sizeof(float), |
src, util_format_get_stride(format, w), |
0, 0, w, h); |
} |
void |
pipe_tile_raw_to_signed(enum pipe_format format, |
void *src, |
uint w, uint h, |
int *dst, unsigned dst_stride) |
{ |
util_format_read_4i(format, |
dst, dst_stride * sizeof(float), |
src, util_format_get_stride(format, w), |
0, 0, w, h); |
} |
void |
pipe_get_tile_rgba(struct pipe_transfer *pt, |
const void *src, |
uint x, uint y, uint w, uint h, |
float *p) |
{ |
pipe_get_tile_rgba_format(pt, src, x, y, w, h, pt->resource->format, p); |
} |
void |
pipe_get_tile_rgba_format(struct pipe_transfer *pt, |
const void *src, |
uint x, uint y, uint w, uint h, |
enum pipe_format format, |
float *p) |
{ |
unsigned dst_stride = w * 4; |
void *packed; |
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(pt, src, x, y, w, h, packed, 0); |
pipe_tile_raw_to_rgba(format, packed, w, h, p, dst_stride); |
FREE(packed); |
} |
void |
pipe_put_tile_rgba(struct pipe_transfer *pt, |
void *dst, |
uint x, uint y, uint w, uint h, |
const float *p) |
{ |
pipe_put_tile_rgba_format(pt, dst, x, y, w, h, pt->resource->format, p); |
} |
void |
pipe_put_tile_rgba_format(struct pipe_transfer *pt, |
void *dst, |
uint x, uint y, uint w, uint h, |
enum pipe_format format, |
const float *p) |
{ |
unsigned src_stride = w * 4; |
void *packed; |
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; |
switch (format) { |
case PIPE_FORMAT_Z16_UNORM: |
/*z16_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/ |
break; |
case PIPE_FORMAT_Z32_UNORM: |
/*z32_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ |
break; |
case PIPE_FORMAT_Z24_UNORM_S8_UINT: |
case PIPE_FORMAT_Z24X8_UNORM: |
/*s8z24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ |
break; |
case PIPE_FORMAT_S8_UINT_Z24_UNORM: |
case PIPE_FORMAT_X8Z24_UNORM: |
/*z24s8_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ |
break; |
case PIPE_FORMAT_Z32_FLOAT: |
/*z32f_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ |
break; |
case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: |
/*z32f_s8x24_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);*/ |
break; |
default: |
util_format_write_4f(format, |
p, src_stride * sizeof(float), |
packed, util_format_get_stride(format, w), |
0, 0, w, h); |
} |
pipe_put_tile_raw(pt, dst, x, y, w, h, packed, 0); |
FREE(packed); |
} |
void |
pipe_put_tile_i_format(struct pipe_transfer *pt, |
void *dst, |
uint x, uint y, uint w, uint h, |
enum pipe_format format, |
const int *p) |
{ |
unsigned src_stride = w * 4; |
void *packed; |
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; |
util_format_write_4i(format, |
p, src_stride * sizeof(float), |
packed, util_format_get_stride(format, w), |
0, 0, w, h); |
pipe_put_tile_raw(pt, dst, x, y, w, h, packed, 0); |
FREE(packed); |
} |
void |
pipe_put_tile_ui_format(struct pipe_transfer *pt, |
void *dst, |
uint x, uint y, uint w, uint h, |
enum pipe_format format, |
const unsigned int *p) |
{ |
unsigned src_stride = w * 4; |
void *packed; |
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; |
util_format_write_4ui(format, |
p, src_stride * sizeof(float), |
packed, util_format_get_stride(format, w), |
0, 0, w, h); |
pipe_put_tile_raw(pt, dst, x, y, w, h, packed, 0); |
FREE(packed); |
} |
/** |
* Get a block of Z values, converted to 32-bit range. |
*/ |
void |
pipe_get_tile_z(struct pipe_transfer *pt, |
const void *src, |
uint x, uint y, uint w, uint h, |
uint *z) |
{ |
const uint dstStride = w; |
const ubyte *map = src; |
uint *pDest = z; |
uint i, j; |
enum pipe_format format = pt->resource->format; |
if (u_clip_tile(x, y, &w, &h, &pt->box)) |
return; |
switch (format) { |
case PIPE_FORMAT_Z32_UNORM: |
{ |
const uint *ptrc |
= (const uint *)(map + y * pt->stride + x*4); |
for (i = 0; i < h; i++) { |
memcpy(pDest, ptrc, 4 * w); |
pDest += dstStride; |
ptrc += pt->stride/4; |
} |
} |
break; |
case PIPE_FORMAT_Z24_UNORM_S8_UINT: |
case PIPE_FORMAT_Z24X8_UNORM: |
{ |
const uint *ptrc |
= (const uint *)(map + y * pt->stride + x*4); |
for (i = 0; i < h; i++) { |
for (j = 0; j < w; j++) { |
/* convert 24-bit Z to 32-bit Z */ |
pDest[j] = (ptrc[j] << 8) | ((ptrc[j] >> 16) & 0xff); |
} |
pDest += dstStride; |
ptrc += pt->stride/4; |
} |
} |
break; |
case PIPE_FORMAT_S8_UINT_Z24_UNORM: |
case PIPE_FORMAT_X8Z24_UNORM: |
{ |
const uint *ptrc |
= (const uint *)(map + y * pt->stride + x*4); |
for (i = 0; i < h; i++) { |
for (j = 0; j < w; j++) { |
/* convert 24-bit Z to 32-bit Z */ |
pDest[j] = (ptrc[j] & 0xffffff00) | ((ptrc[j] >> 24) & 0xff); |
} |
pDest += dstStride; |
ptrc += pt->stride/4; |
} |
} |
break; |
case PIPE_FORMAT_Z16_UNORM: |
{ |
const ushort *ptrc |
= (const ushort *)(map + y * pt->stride + x*2); |
for (i = 0; i < h; i++) { |
for (j = 0; j < w; j++) { |
/* convert 16-bit Z to 32-bit Z */ |
pDest[j] = (ptrc[j] << 16) | ptrc[j]; |
} |
pDest += dstStride; |
ptrc += pt->stride/2; |
} |
} |
break; |
case PIPE_FORMAT_Z32_FLOAT: |
{ |
const float *ptrc = (const float *)(map + y * pt->stride + x*4); |
for (i = 0; i < h; i++) { |
for (j = 0; j < w; j++) { |
/* convert float Z to 32-bit Z */ |
if (ptrc[j] <= 0.0) { |
pDest[j] = 0; |
} |
else if (ptrc[j] >= 1.0) { |
pDest[j] = 0xffffffff; |
} |
else { |
double z = ptrc[j] * 0xffffffff; |
pDest[j] = (uint) z; |
} |
} |
pDest += dstStride; |
ptrc += pt->stride/4; |
} |
} |
break; |
case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: |
{ |
const float *ptrc = (const float *)(map + y * pt->stride + x*8); |
for (i = 0; i < h; i++) { |
for (j = 0; j < w; j++) { |
/* convert float Z to 32-bit Z */ |
if (ptrc[j] <= 0.0) { |
pDest[j*2] = 0; |
} |
else if (ptrc[j] >= 1.0) { |
pDest[j*2] = 0xffffffff; |
} |
else { |
double z = ptrc[j] * 0xffffffff; |
pDest[j*2] = (uint) z; |
} |
} |
pDest += dstStride; |
ptrc += pt->stride/4; |
} |
} |
break; |
default: |
assert(0); |
} |
} |
void |
pipe_put_tile_z(struct pipe_transfer *pt, |
void *dst, |
uint x, uint y, uint w, uint h, |
const uint *zSrc) |
{ |
const uint srcStride = w; |
const uint *ptrc = zSrc; |
ubyte *map = dst; |
uint i, j; |
enum pipe_format format = pt->resource->format; |
if (u_clip_tile(x, y, &w, &h, &pt->box)) |
return; |
switch (format) { |
case PIPE_FORMAT_Z32_UNORM: |
{ |
uint *pDest = (uint *) (map + y * pt->stride + x*4); |
for (i = 0; i < h; i++) { |
memcpy(pDest, ptrc, 4 * w); |
pDest += pt->stride/4; |
ptrc += srcStride; |
} |
} |
break; |
case PIPE_FORMAT_Z24_UNORM_S8_UINT: |
{ |
uint *pDest = (uint *) (map + y * pt->stride + x*4); |
/*assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE);*/ |
for (i = 0; i < h; i++) { |
for (j = 0; j < w; j++) { |
/* convert 32-bit Z to 24-bit Z, preserve stencil */ |
pDest[j] = (pDest[j] & 0xff000000) | ptrc[j] >> 8; |
} |
pDest += pt->stride/4; |
ptrc += srcStride; |
} |
} |
break; |
case PIPE_FORMAT_Z24X8_UNORM: |
{ |
uint *pDest = (uint *) (map + y * pt->stride + x*4); |
for (i = 0; i < h; i++) { |
for (j = 0; j < w; j++) { |
/* convert 32-bit Z to 24-bit Z (0 stencil) */ |
pDest[j] = ptrc[j] >> 8; |
} |
pDest += pt->stride/4; |
ptrc += srcStride; |
} |
} |
break; |
case PIPE_FORMAT_S8_UINT_Z24_UNORM: |
{ |
uint *pDest = (uint *) (map + y * pt->stride + x*4); |
/*assert((pt->usage & PIPE_TRANSFER_READ_WRITE) == PIPE_TRANSFER_READ_WRITE);*/ |
for (i = 0; i < h; i++) { |
for (j = 0; j < w; j++) { |
/* convert 32-bit Z to 24-bit Z, preserve stencil */ |
pDest[j] = (pDest[j] & 0xff) | (ptrc[j] & 0xffffff00); |
} |
pDest += pt->stride/4; |
ptrc += srcStride; |
} |
} |
break; |
case PIPE_FORMAT_X8Z24_UNORM: |
{ |
uint *pDest = (uint *) (map + y * pt->stride + x*4); |
for (i = 0; i < h; i++) { |
for (j = 0; j < w; j++) { |
/* convert 32-bit Z to 24-bit Z (0 stencil) */ |
pDest[j] = ptrc[j] & 0xffffff00; |
} |
pDest += pt->stride/4; |
ptrc += srcStride; |
} |
} |
break; |
case PIPE_FORMAT_Z16_UNORM: |
{ |
ushort *pDest = (ushort *) (map + y * pt->stride + x*2); |
for (i = 0; i < h; i++) { |
for (j = 0; j < w; j++) { |
/* convert 32-bit Z to 16-bit Z */ |
pDest[j] = ptrc[j] >> 16; |
} |
pDest += pt->stride/2; |
ptrc += srcStride; |
} |
} |
break; |
case PIPE_FORMAT_Z32_FLOAT: |
{ |
float *pDest = (float *) (map + y * pt->stride + x*4); |
for (i = 0; i < h; i++) { |
for (j = 0; j < w; j++) { |
/* convert 32-bit integer Z to float Z */ |
const double scale = 1.0 / 0xffffffffU; |
pDest[j] = (float) (ptrc[j] * scale); |
} |
pDest += pt->stride/4; |
ptrc += srcStride; |
} |
} |
break; |
case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: |
{ |
float *pDest = (float *) (map + y * pt->stride + x*8); |
for (i = 0; i < h; i++) { |
for (j = 0; j < w; j++) { |
/* convert 32-bit integer Z to float Z */ |
const double scale = 1.0 / 0xffffffffU; |
pDest[j*2] = (float) (ptrc[j] * scale); |
} |
pDest += pt->stride/4; |
ptrc += srcStride; |
} |
} |
break; |
default: |
assert(0); |
} |
} |
void |
pipe_get_tile_ui_format(struct pipe_transfer *pt, |
const void *src, |
uint x, uint y, uint w, uint h, |
enum pipe_format format, |
unsigned int *p) |
{ |
unsigned dst_stride = w * 4; |
void *packed; |
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(pt, src, x, y, w, h, packed, 0); |
pipe_tile_raw_to_unsigned(format, packed, w, h, p, dst_stride); |
FREE(packed); |
} |
void |
pipe_get_tile_i_format(struct pipe_transfer *pt, |
const void *src, |
uint x, uint y, uint w, uint h, |
enum pipe_format format, |
int *p) |
{ |
unsigned dst_stride = w * 4; |
void *packed; |
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(pt, src, x, y, w, h, packed, 0); |
pipe_tile_raw_to_signed(format, packed, w, h, p, dst_stride); |
FREE(packed); |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_tile.h |
---|
0,0 → 1,165 |
/************************************************************************** |
* |
* Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. |
* 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 TUNGSTEN GRAPHICS 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 P_TILE_H |
#define P_TILE_H |
#include "pipe/p_compiler.h" |
#include "pipe/p_format.h" |
#include "pipe/p_state.h" |
struct pipe_context; |
struct pipe_transfer; |
/** |
* Clip tile against transfer dims. |
* |
* XXX: this only clips width and height! |
* |
* \return TRUE if tile is totally clipped, FALSE otherwise |
*/ |
static INLINE boolean |
u_clip_tile(uint x, uint y, uint *w, uint *h, const struct pipe_box *box) |
{ |
if ((int) x >= box->width) |
return TRUE; |
if ((int) y >= box->height) |
return TRUE; |
if ((int) (x + *w) > box->width) |
*w = box->width - x; |
if ((int) (y + *h) > box->height) |
*h = box->height - y; |
return FALSE; |
} |
#ifdef __cplusplus |
extern "C" { |
#endif |
void |
pipe_get_tile_raw(struct pipe_transfer *pt, |
const void *src, |
uint x, uint y, uint w, uint h, |
void *p, int dst_stride); |
void |
pipe_put_tile_raw(struct pipe_transfer *pt, |
void *dst, |
uint x, uint y, uint w, uint h, |
const void *p, int src_stride); |
void |
pipe_get_tile_rgba(struct pipe_transfer *pt, |
const void *src, |
uint x, uint y, uint w, uint h, |
float *p); |
void |
pipe_get_tile_rgba_format(struct pipe_transfer *pt, |
const void *src, |
uint x, uint y, uint w, uint h, |
enum pipe_format format, |
float *p); |
void |
pipe_put_tile_rgba(struct pipe_transfer *pt, |
void *dst, |
uint x, uint y, uint w, uint h, |
const float *p); |
void |
pipe_put_tile_rgba_format(struct pipe_transfer *pt, |
void *dst, |
uint x, uint y, uint w, uint h, |
enum pipe_format format, |
const float *p); |
void |
pipe_get_tile_z(struct pipe_transfer *pt, |
const void *src, |
uint x, uint y, uint w, uint h, |
uint *z); |
void |
pipe_put_tile_z(struct pipe_transfer *pt, |
void *dst, |
uint x, uint y, uint w, uint h, |
const uint *z); |
void |
pipe_tile_raw_to_rgba(enum pipe_format format, |
const void *src, |
uint w, uint h, |
float *dst, unsigned dst_stride); |
void |
pipe_tile_raw_to_unsigned(enum pipe_format format, |
const void *src, |
uint w, uint h, |
unsigned *dst, unsigned dst_stride); |
void |
pipe_tile_raw_to_signed(enum pipe_format format, |
void *src, |
uint w, uint h, |
int *dst, unsigned dst_stride); |
void |
pipe_get_tile_ui_format(struct pipe_transfer *pt, |
const void *src, |
uint x, uint y, uint w, uint h, |
enum pipe_format format, |
unsigned int *p); |
void |
pipe_get_tile_i_format(struct pipe_transfer *pt, |
const void *src, |
uint x, uint y, uint w, uint h, |
enum pipe_format format, |
int *p); |
void |
pipe_put_tile_ui_format(struct pipe_transfer *pt, |
void *dst, |
uint x, uint y, uint w, uint h, |
enum pipe_format format, |
const unsigned *p); |
void |
pipe_put_tile_i_format(struct pipe_transfer *pt, |
void *dst, |
uint x, uint y, uint w, uint h, |
enum pipe_format format, |
const int *p); |
#ifdef __cplusplus |
} |
#endif |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_time.h |
---|
0,0 → 1,150 |
/************************************************************************** |
* |
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. |
* 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 TUNGSTEN GRAPHICS 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. |
* |
**************************************************************************/ |
/** |
* @file |
* OS independent time-manipulation functions. |
* |
* @author Jose Fonseca <jrfonseca@tungstengraphics.com> |
*/ |
#ifndef U_TIME_H_ |
#define U_TIME_H_ |
#include "pipe/p_config.h" |
#include "os/os_time.h" |
#include "pipe/p_compiler.h" |
#ifdef __cplusplus |
extern "C" { |
#endif |
/** |
* Time abstraction. |
* |
* Do not access this structure directly. Use the provided function instead. |
*/ |
struct util_time |
{ |
int64_t counter; |
}; |
PIPE_DEPRECATED |
static INLINE void |
util_time_get(struct util_time *t) |
{ |
t->counter = os_time_get(); |
} |
/** |
* Return t2 = t1 + usecs |
*/ |
PIPE_DEPRECATED |
static INLINE void |
util_time_add(const struct util_time *t1, |
int64_t usecs, |
struct util_time *t2) |
{ |
t2->counter = t1->counter + usecs; |
} |
/** |
* Return difference between times, in microseconds |
*/ |
PIPE_DEPRECATED |
static INLINE int64_t |
util_time_diff(const struct util_time *t1, |
const struct util_time *t2) |
{ |
return t2->counter - t1->counter; |
} |
/** |
* Compare two time values. |
* |
* Not publicly available because it does not take in account wrap-arounds. |
* Use util_time_timeout instead. |
*/ |
static INLINE int |
_util_time_compare(const struct util_time *t1, |
const struct util_time *t2) |
{ |
if (t1->counter < t2->counter) |
return -1; |
else if(t1->counter > t2->counter) |
return 1; |
else |
return 0; |
} |
/** |
* Returns non-zero when the timeout expires. |
*/ |
PIPE_DEPRECATED |
static INLINE boolean |
util_time_timeout(const struct util_time *start, |
const struct util_time *end, |
const struct util_time *curr) |
{ |
return os_time_timeout(start->counter, end->counter, curr->counter); |
} |
/** |
* Return current time in microseconds |
*/ |
PIPE_DEPRECATED |
static INLINE int64_t |
util_time_micros(void) |
{ |
return os_time_get(); |
} |
PIPE_DEPRECATED |
static INLINE void |
util_time_sleep(int64_t usecs) |
{ |
os_time_sleep(usecs); |
} |
#ifdef __cplusplus |
} |
#endif |
#endif /* U_TIME_H_ */ |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_transfer.c |
---|
0,0 → 1,163 |
#include "pipe/p_context.h" |
#include "util/u_surface.h" |
#include "util/u_inlines.h" |
#include "util/u_transfer.h" |
#include "util/u_memory.h" |
/* One-shot transfer operation with data supplied in a user |
* pointer. XXX: strides?? |
*/ |
void u_default_transfer_inline_write( struct pipe_context *pipe, |
struct pipe_resource *resource, |
unsigned level, |
unsigned usage, |
const struct pipe_box *box, |
const void *data, |
unsigned stride, |
unsigned layer_stride) |
{ |
struct pipe_transfer *transfer = NULL; |
uint8_t *map = NULL; |
assert(!(usage & PIPE_TRANSFER_READ)); |
/* the write flag is implicit by the nature of transfer_inline_write */ |
usage |= PIPE_TRANSFER_WRITE; |
/* transfer_inline_write implicitly discards the rewritten buffer range */ |
/* XXX this looks very broken for non-buffer resources having more than one dim. */ |
if (box->x == 0 && box->width == resource->width0) { |
usage |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE; |
} else { |
usage |= PIPE_TRANSFER_DISCARD_RANGE; |
} |
map = pipe->transfer_map(pipe, |
resource, |
level, |
usage, |
box, &transfer); |
if (map == NULL) |
return; |
if (resource->target == PIPE_BUFFER) { |
assert(box->height == 1); |
assert(box->depth == 1); |
memcpy(map, data, box->width); |
} |
else { |
const uint8_t *src_data = data; |
util_copy_box(map, |
resource->format, |
transfer->stride, /* bytes */ |
transfer->layer_stride, /* bytes */ |
0, 0, 0, |
box->width, |
box->height, |
box->depth, |
src_data, |
stride, /* bytes */ |
layer_stride, /* bytes */ |
0, 0, 0); |
} |
pipe_transfer_unmap(pipe, transfer); |
} |
boolean u_default_resource_get_handle(struct pipe_screen *screen, |
struct pipe_resource *resource, |
struct winsys_handle *handle) |
{ |
return FALSE; |
} |
void u_default_transfer_flush_region( struct pipe_context *pipe, |
struct pipe_transfer *transfer, |
const struct pipe_box *box) |
{ |
/* This is a no-op implementation, nothing to do. |
*/ |
} |
void u_default_transfer_unmap( struct pipe_context *pipe, |
struct pipe_transfer *transfer ) |
{ |
} |
static INLINE struct u_resource * |
u_resource( struct pipe_resource *res ) |
{ |
return (struct u_resource *)res; |
} |
boolean u_resource_get_handle_vtbl(struct pipe_screen *screen, |
struct pipe_resource *resource, |
struct winsys_handle *handle) |
{ |
struct u_resource *ur = u_resource(resource); |
return ur->vtbl->resource_get_handle(screen, resource, handle); |
} |
void u_resource_destroy_vtbl(struct pipe_screen *screen, |
struct pipe_resource *resource) |
{ |
struct u_resource *ur = u_resource(resource); |
ur->vtbl->resource_destroy(screen, resource); |
} |
void *u_transfer_map_vtbl(struct pipe_context *context, |
struct pipe_resource *resource, |
unsigned level, |
unsigned usage, |
const struct pipe_box *box, |
struct pipe_transfer **transfer) |
{ |
struct u_resource *ur = u_resource(resource); |
return ur->vtbl->transfer_map(context, resource, level, usage, box, |
transfer); |
} |
void u_transfer_flush_region_vtbl( struct pipe_context *pipe, |
struct pipe_transfer *transfer, |
const struct pipe_box *box) |
{ |
struct u_resource *ur = u_resource(transfer->resource); |
ur->vtbl->transfer_flush_region(pipe, transfer, box); |
} |
void u_transfer_unmap_vtbl( struct pipe_context *pipe, |
struct pipe_transfer *transfer ) |
{ |
struct u_resource *ur = u_resource(transfer->resource); |
ur->vtbl->transfer_unmap(pipe, transfer); |
} |
void u_transfer_inline_write_vtbl( struct pipe_context *pipe, |
struct pipe_resource *resource, |
unsigned level, |
unsigned usage, |
const struct pipe_box *box, |
const void *data, |
unsigned stride, |
unsigned layer_stride) |
{ |
struct u_resource *ur = u_resource(resource); |
ur->vtbl->transfer_inline_write(pipe, |
resource, |
level, |
usage, |
box, |
data, |
stride, |
layer_stride); |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_transfer.h |
---|
0,0 → 1,109 |
#ifndef U_TRANSFER_H |
#define U_TRANSFER_H |
/* Fallback implementations for inline read/writes which just go back |
* to the regular transfer behaviour. |
*/ |
#include "pipe/p_state.h" |
struct pipe_context; |
struct winsys_handle; |
boolean u_default_resource_get_handle(struct pipe_screen *screen, |
struct pipe_resource *resource, |
struct winsys_handle *handle); |
void u_default_transfer_inline_write( struct pipe_context *pipe, |
struct pipe_resource *resource, |
unsigned level, |
unsigned usage, |
const struct pipe_box *box, |
const void *data, |
unsigned stride, |
unsigned layer_stride); |
void u_default_transfer_flush_region( struct pipe_context *pipe, |
struct pipe_transfer *transfer, |
const struct pipe_box *box); |
void u_default_transfer_unmap( struct pipe_context *pipe, |
struct pipe_transfer *transfer ); |
/* Useful helper to allow >1 implementation of resource functionality |
* to exist in a single driver. This is intended to be transitionary! |
*/ |
struct u_resource_vtbl { |
boolean (*resource_get_handle)(struct pipe_screen *, |
struct pipe_resource *tex, |
struct winsys_handle *handle); |
void (*resource_destroy)(struct pipe_screen *, |
struct pipe_resource *pt); |
void *(*transfer_map)(struct pipe_context *, |
struct pipe_resource *resource, |
unsigned level, |
unsigned usage, |
const struct pipe_box *, |
struct pipe_transfer **); |
void (*transfer_flush_region)( struct pipe_context *, |
struct pipe_transfer *transfer, |
const struct pipe_box *); |
void (*transfer_unmap)( struct pipe_context *, |
struct pipe_transfer *transfer ); |
void (*transfer_inline_write)( struct pipe_context *pipe, |
struct pipe_resource *resource, |
unsigned level, |
unsigned usage, |
const struct pipe_box *box, |
const void *data, |
unsigned stride, |
unsigned layer_stride); |
}; |
struct u_resource { |
struct pipe_resource b; |
const struct u_resource_vtbl *vtbl; |
}; |
boolean u_resource_get_handle_vtbl(struct pipe_screen *screen, |
struct pipe_resource *resource, |
struct winsys_handle *handle); |
void u_resource_destroy_vtbl(struct pipe_screen *screen, |
struct pipe_resource *resource); |
void *u_transfer_map_vtbl(struct pipe_context *context, |
struct pipe_resource *resource, |
unsigned level, |
unsigned usage, |
const struct pipe_box *box, |
struct pipe_transfer **transfer); |
void u_transfer_flush_region_vtbl( struct pipe_context *pipe, |
struct pipe_transfer *transfer, |
const struct pipe_box *box); |
void u_transfer_unmap_vtbl( struct pipe_context *rm_ctx, |
struct pipe_transfer *transfer ); |
void u_transfer_inline_write_vtbl( struct pipe_context *rm_ctx, |
struct pipe_resource *resource, |
unsigned level, |
unsigned usage, |
const struct pipe_box *box, |
const void *data, |
unsigned stride, |
unsigned layer_stride); |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_upload_mgr.c |
---|
0,0 → 1,271 |
/************************************************************************** |
* |
* Copyright 2009 VMware, Inc. |
* 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 VMWARE 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. |
* |
**************************************************************************/ |
/* Helper utility for uploading user buffers & other data, and |
* coalescing small buffers into larger ones. |
*/ |
#include "pipe/p_defines.h" |
#include "util/u_inlines.h" |
#include "pipe/p_context.h" |
#include "util/u_memory.h" |
#include "util/u_math.h" |
#include "u_upload_mgr.h" |
struct u_upload_mgr { |
struct pipe_context *pipe; |
unsigned default_size; /* Minimum size of the upload buffer, in bytes. */ |
unsigned alignment; /* Alignment of each sub-allocation. */ |
unsigned bind; /* Bitmask of PIPE_BIND_* flags. */ |
struct pipe_resource *buffer; /* Upload buffer. */ |
struct pipe_transfer *transfer; /* Transfer object for the upload buffer. */ |
uint8_t *map; /* Pointer to the mapped upload buffer. */ |
unsigned size; /* Actual size of the upload buffer. */ |
unsigned offset; /* Aligned offset to the upload buffer, pointing |
* at the first unused byte. */ |
}; |
struct u_upload_mgr *u_upload_create( struct pipe_context *pipe, |
unsigned default_size, |
unsigned alignment, |
unsigned bind ) |
{ |
struct u_upload_mgr *upload = CALLOC_STRUCT( u_upload_mgr ); |
if (!upload) |
return NULL; |
upload->pipe = pipe; |
upload->default_size = default_size; |
upload->alignment = alignment; |
upload->bind = bind; |
upload->buffer = NULL; |
return upload; |
} |
void u_upload_unmap( struct u_upload_mgr *upload ) |
{ |
if (upload->transfer) { |
struct pipe_box *box = &upload->transfer->box; |
if ((int) upload->offset > box->x) { |
pipe_buffer_flush_mapped_range(upload->pipe, upload->transfer, |
box->x, upload->offset - box->x); |
} |
pipe_transfer_unmap(upload->pipe, upload->transfer); |
upload->transfer = NULL; |
upload->map = NULL; |
} |
} |
/* Release old buffer. |
* |
* This must usually be called prior to firing the command stream |
* which references the upload buffer, as many memory managers will |
* cause subsequent maps of a fired buffer to wait. |
* |
* Can improve this with a change to pipe_buffer_write to use the |
* DONT_WAIT bit, but for now, it's easiest just to grab a new buffer. |
*/ |
void u_upload_flush( struct u_upload_mgr *upload ) |
{ |
/* Unmap and unreference the upload buffer. */ |
u_upload_unmap(upload); |
pipe_resource_reference( &upload->buffer, NULL ); |
upload->size = 0; |
} |
void u_upload_destroy( struct u_upload_mgr *upload ) |
{ |
u_upload_flush( upload ); |
FREE( upload ); |
} |
static enum pipe_error |
u_upload_alloc_buffer( struct u_upload_mgr *upload, |
unsigned min_size ) |
{ |
unsigned size; |
/* Release the old buffer, if present: |
*/ |
u_upload_flush( upload ); |
/* Allocate a new one: |
*/ |
size = align(MAX2(upload->default_size, min_size), 4096); |
upload->buffer = pipe_buffer_create( upload->pipe->screen, |
upload->bind, |
PIPE_USAGE_STREAM, |
size ); |
if (upload->buffer == NULL) { |
return PIPE_ERROR_OUT_OF_MEMORY; |
} |
/* Map the new buffer. */ |
upload->map = pipe_buffer_map_range(upload->pipe, upload->buffer, |
0, size, |
PIPE_TRANSFER_WRITE | |
PIPE_TRANSFER_FLUSH_EXPLICIT, |
&upload->transfer); |
if (upload->map == NULL) { |
upload->transfer = NULL; |
upload->size = 0; |
pipe_resource_reference(&upload->buffer, NULL); |
return PIPE_ERROR_OUT_OF_MEMORY; |
} |
upload->size = size; |
upload->offset = 0; |
return PIPE_OK; |
} |
enum pipe_error u_upload_alloc( struct u_upload_mgr *upload, |
unsigned min_out_offset, |
unsigned size, |
unsigned *out_offset, |
struct pipe_resource **outbuf, |
void **ptr ) |
{ |
unsigned alloc_size = align( size, upload->alignment ); |
unsigned alloc_offset = align(min_out_offset, upload->alignment); |
unsigned offset; |
/* Init these return values here in case we fail below to make |
* sure the caller doesn't get garbage values. |
*/ |
*out_offset = ~0; |
pipe_resource_reference(outbuf, NULL); |
*ptr = NULL; |
/* Make sure we have enough space in the upload buffer |
* for the sub-allocation. */ |
if (MAX2(upload->offset, alloc_offset) + alloc_size > upload->size) { |
enum pipe_error ret = u_upload_alloc_buffer(upload, |
alloc_offset + alloc_size); |
if (ret != PIPE_OK) |
return ret; |
} |
offset = MAX2(upload->offset, alloc_offset); |
if (!upload->map) { |
upload->map = pipe_buffer_map_range(upload->pipe, upload->buffer, |
offset, upload->size - offset, |
PIPE_TRANSFER_WRITE | |
PIPE_TRANSFER_FLUSH_EXPLICIT | |
PIPE_TRANSFER_UNSYNCHRONIZED, |
&upload->transfer); |
if (!upload->map) { |
upload->transfer = NULL; |
return PIPE_ERROR_OUT_OF_MEMORY; |
} |
upload->map -= offset; |
} |
assert(offset < upload->buffer->width0); |
assert(offset + size <= upload->buffer->width0); |
assert(size); |
/* Emit the return values: */ |
*ptr = upload->map + offset; |
pipe_resource_reference( outbuf, upload->buffer ); |
*out_offset = offset; |
upload->offset = offset + alloc_size; |
return PIPE_OK; |
} |
enum pipe_error u_upload_data( struct u_upload_mgr *upload, |
unsigned min_out_offset, |
unsigned size, |
const void *data, |
unsigned *out_offset, |
struct pipe_resource **outbuf) |
{ |
uint8_t *ptr; |
enum pipe_error ret = u_upload_alloc(upload, min_out_offset, size, |
out_offset, outbuf, |
(void**)&ptr); |
if (ret != PIPE_OK) |
return ret; |
memcpy(ptr, data, size); |
return PIPE_OK; |
} |
/* As above, but upload the full contents of a buffer. Useful for |
* uploading user buffers, avoids generating an explosion of GPU |
* buffers if you have an app that does lots of small vertex buffer |
* renders or DrawElements calls. |
*/ |
enum pipe_error u_upload_buffer( struct u_upload_mgr *upload, |
unsigned min_out_offset, |
unsigned offset, |
unsigned size, |
struct pipe_resource *inbuf, |
unsigned *out_offset, |
struct pipe_resource **outbuf) |
{ |
enum pipe_error ret = PIPE_OK; |
struct pipe_transfer *transfer = NULL; |
const char *map = NULL; |
map = (const char *)pipe_buffer_map_range(upload->pipe, |
inbuf, |
offset, size, |
PIPE_TRANSFER_READ, |
&transfer); |
if (map == NULL) { |
return PIPE_ERROR_OUT_OF_MEMORY; |
} |
if (0) |
debug_printf("upload ptr %p ofs %d sz %d\n", map, offset, size); |
ret = u_upload_data( upload, |
min_out_offset, |
size, |
map, |
out_offset, |
outbuf); |
pipe_buffer_unmap( upload->pipe, transfer ); |
return ret; |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_upload_mgr.h |
---|
0,0 → 1,130 |
/************************************************************************** |
* |
* Copyright 2009 VMware, Inc. |
* 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 VMWARE 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. |
* |
**************************************************************************/ |
/* Helper utility for uploading user buffers & other data, and |
* coalescing small buffers into larger ones. |
*/ |
#ifndef U_UPLOAD_MGR_H |
#define U_UPLOAD_MGR_H |
#include "pipe/p_compiler.h" |
struct pipe_context; |
struct pipe_resource; |
/** |
* Create the upload manager. |
* |
* \param pipe Pipe driver. |
* \param default_size Minimum size of the upload buffer, in bytes. |
* \param alignment Alignment of each suballocation in the upload buffer. |
* \param bind Bitmask of PIPE_BIND_* flags. |
*/ |
struct u_upload_mgr *u_upload_create( struct pipe_context *pipe, |
unsigned default_size, |
unsigned alignment, |
unsigned bind ); |
/** |
* Destroy the upload manager. |
*/ |
void u_upload_destroy( struct u_upload_mgr *upload ); |
/** |
* Unmap and release old upload buffer. |
* |
* This is like u_upload_unmap() except the upload buffer is released for |
* recycling. This should be called on real hardware flushes on systems |
* that don't support the PIPE_TRANSFER_UNSYNCHRONIZED flag, as otherwise |
* the next u_upload_buffer will cause a sync on the buffer. |
*/ |
void u_upload_flush( struct u_upload_mgr *upload ); |
/** |
* Unmap upload buffer |
* |
* \param upload Upload manager |
* |
* This must usually be called prior to firing the command stream |
* which references the upload buffer, as many memory managers either |
* don't like firing a mapped buffer or cause subsequent maps of a |
* fired buffer to wait. |
*/ |
void u_upload_unmap( struct u_upload_mgr *upload ); |
/** |
* Sub-allocate new memory from the upload buffer. |
* |
* \param upload Upload manager |
* \param min_out_offset Minimum offset that should be returned in out_offset. |
* \param size Size of the allocation. |
* \param out_offset Pointer to where the new buffer offset will be returned. |
* \param outbuf Pointer to where the upload buffer will be returned. |
* \param ptr Pointer to the allocated memory that is returned. |
*/ |
enum pipe_error u_upload_alloc( struct u_upload_mgr *upload, |
unsigned min_out_offset, |
unsigned size, |
unsigned *out_offset, |
struct pipe_resource **outbuf, |
void **ptr ); |
/** |
* Allocate and write data to the upload buffer. |
* |
* Same as u_upload_alloc, but in addition to that, it copies "data" |
* to the pointer returned from u_upload_alloc. |
*/ |
enum pipe_error u_upload_data( struct u_upload_mgr *upload, |
unsigned min_out_offset, |
unsigned size, |
const void *data, |
unsigned *out_offset, |
struct pipe_resource **outbuf); |
/** |
* Allocate space in an upload buffer and copy an input buffer to it. |
* |
* Same as u_upload_data, except that the input data comes from a buffer |
* instead of a user pointer. |
*/ |
enum pipe_error u_upload_buffer( struct u_upload_mgr *upload, |
unsigned min_out_offset, |
unsigned offset, |
unsigned size, |
struct pipe_resource *inbuf, |
unsigned *out_offset, |
struct pipe_resource **outbuf); |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_vbuf.c |
---|
0,0 → 1,1295 |
/************************************************************************** |
* |
* Copyright 2011 Marek Olšák <maraeo@gmail.com> |
* 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. |
* |
**************************************************************************/ |
/** |
* This module uploads user buffers and translates the vertex buffers which |
* contain incompatible vertices (i.e. not supported by the driver/hardware) |
* into compatible ones, based on the Gallium CAPs. |
* |
* It does not upload index buffers. |
* |
* The module heavily uses bitmasks to represent per-buffer and |
* per-vertex-element flags to avoid looping over the list of buffers just |
* to see if there's a non-zero stride, or user buffer, or unsupported format, |
* etc. |
* |
* There are 3 categories of vertex elements, which are processed separately: |
* - per-vertex attribs (stride != 0, instance_divisor == 0) |
* - instanced attribs (stride != 0, instance_divisor > 0) |
* - constant attribs (stride == 0) |
* |
* All needed uploads and translations are performed every draw command, but |
* only the subset of vertices needed for that draw command is uploaded or |
* translated. (the module never translates whole buffers) |
* |
* |
* The module consists of two main parts: |
* |
* |
* 1) Translate (u_vbuf_translate_begin/end) |
* |
* This is pretty much a vertex fetch fallback. It translates vertices from |
* one vertex buffer to another in an unused vertex buffer slot. It does |
* whatever is needed to make the vertices readable by the hardware (changes |
* vertex formats and aligns offsets and strides). The translate module is |
* used here. |
* |
* Each of the 3 categories is translated to a separate buffer. |
* Only the [min_index, max_index] range is translated. For instanced attribs, |
* the range is [start_instance, start_instance+instance_count]. For constant |
* attribs, the range is [0, 1]. |
* |
* |
* 2) User buffer uploading (u_vbuf_upload_buffers) |
* |
* Only the [min_index, max_index] range is uploaded (just like Translate) |
* with a single memcpy. |
* |
* This method works best for non-indexed draw operations or indexed draw |
* operations where the [min_index, max_index] range is not being way bigger |
* than the vertex count. |
* |
* If the range is too big (e.g. one triangle with indices {0, 1, 10000}), |
* the per-vertex attribs are uploaded via the translate module, all packed |
* into one vertex buffer, and the indexed draw call is turned into |
* a non-indexed one in the process. This adds additional complexity |
* to the translate part, but it prevents bad apps from bringing your frame |
* rate down. |
* |
* |
* If there is nothing to do, it forwards every command to the driver. |
* The module also has its own CSO cache of vertex element states. |
*/ |
#include "util/u_vbuf.h" |
#include "util/u_dump.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" |
#include "cso_cache/cso_cache.h" |
#include "cso_cache/cso_hash.h" |
struct u_vbuf_elements { |
unsigned count; |
struct pipe_vertex_element ve[PIPE_MAX_ATTRIBS]; |
unsigned src_format_size[PIPE_MAX_ATTRIBS]; |
/* If (velem[i].src_format != native_format[i]), the vertex buffer |
* referenced by the vertex element cannot be used for rendering and |
* its vertex data must be translated to native_format[i]. */ |
enum pipe_format native_format[PIPE_MAX_ATTRIBS]; |
unsigned native_format_size[PIPE_MAX_ATTRIBS]; |
/* Which buffers are used by the vertex element state. */ |
uint32_t used_vb_mask; |
/* 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). */ |
uint32_t incompatible_elem_mask; /* each bit describes a corresp. attrib */ |
/* Which buffer has at least one vertex element referencing it |
* incompatible. */ |
uint32_t incompatible_vb_mask_any; |
/* Which buffer has all vertex elements referencing it incompatible. */ |
uint32_t incompatible_vb_mask_all; |
/* Which buffer has at least one vertex element referencing it |
* compatible. */ |
uint32_t compatible_vb_mask_any; |
/* Which buffer has all vertex elements referencing it compatible. */ |
uint32_t compatible_vb_mask_all; |
/* Which buffer has at least one vertex element referencing it |
* non-instanced. */ |
uint32_t noninstance_vb_mask_any; |
void *driver_cso; |
}; |
enum { |
VB_VERTEX = 0, |
VB_INSTANCE = 1, |
VB_CONST = 2, |
VB_NUM = 3 |
}; |
struct u_vbuf { |
struct u_vbuf_caps caps; |
struct pipe_context *pipe; |
struct translate_cache *translate_cache; |
struct cso_cache *cso_cache; |
struct u_upload_mgr *uploader; |
/* This is what was set in set_vertex_buffers. |
* May contain user buffers. */ |
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; |
uint32_t enabled_vb_mask; |
/* Saved vertex buffer. */ |
unsigned aux_vertex_buffer_slot; |
struct pipe_vertex_buffer aux_vertex_buffer_saved; |
/* Vertex buffers for the driver. |
* There are usually no user buffers. */ |
struct pipe_vertex_buffer real_vertex_buffer[PIPE_MAX_ATTRIBS]; |
uint32_t dirty_real_vb_mask; /* which buffers are dirty since the last |
call of set_vertex_buffers */ |
/* The index buffer. */ |
struct pipe_index_buffer index_buffer; |
/* Vertex elements. */ |
struct u_vbuf_elements *ve, *ve_saved; |
/* Vertex elements used for the translate fallback. */ |
struct pipe_vertex_element fallback_velems[PIPE_MAX_ATTRIBS]; |
/* If non-NULL, this is a vertex element state used for the translate |
* fallback and therefore used for rendering too. */ |
boolean using_translate; |
/* The vertex buffer slot index where translated vertices have been |
* stored in. */ |
unsigned fallback_vbs[VB_NUM]; |
/* Which buffer is a user buffer. */ |
uint32_t user_vb_mask; /* each bit describes a corresp. buffer */ |
/* Which buffer is incompatible (unaligned). */ |
uint32_t incompatible_vb_mask; /* each bit describes a corresp. buffer */ |
/* Which buffer has a non-zero stride. */ |
uint32_t nonzero_stride_vb_mask; /* each bit describes a corresp. buffer */ |
}; |
static void * |
u_vbuf_create_vertex_elements(struct u_vbuf *mgr, unsigned count, |
const struct pipe_vertex_element *attribs); |
static void u_vbuf_delete_vertex_elements(struct u_vbuf *mgr, void *cso); |
void u_vbuf_get_caps(struct pipe_screen *screen, struct u_vbuf_caps *caps) |
{ |
caps->format_fixed32 = |
screen->is_format_supported(screen, PIPE_FORMAT_R32_FIXED, PIPE_BUFFER, |
0, PIPE_BIND_VERTEX_BUFFER); |
caps->format_float16 = |
screen->is_format_supported(screen, PIPE_FORMAT_R16_FLOAT, PIPE_BUFFER, |
0, PIPE_BIND_VERTEX_BUFFER); |
caps->format_float64 = |
screen->is_format_supported(screen, PIPE_FORMAT_R64_FLOAT, PIPE_BUFFER, |
0, PIPE_BIND_VERTEX_BUFFER); |
caps->format_norm32 = |
screen->is_format_supported(screen, PIPE_FORMAT_R32_UNORM, PIPE_BUFFER, |
0, PIPE_BIND_VERTEX_BUFFER) && |
screen->is_format_supported(screen, PIPE_FORMAT_R32_SNORM, PIPE_BUFFER, |
0, PIPE_BIND_VERTEX_BUFFER); |
caps->format_scaled32 = |
screen->is_format_supported(screen, PIPE_FORMAT_R32_USCALED, PIPE_BUFFER, |
0, PIPE_BIND_VERTEX_BUFFER) && |
screen->is_format_supported(screen, PIPE_FORMAT_R32_SSCALED, PIPE_BUFFER, |
0, PIPE_BIND_VERTEX_BUFFER); |
caps->buffer_offset_unaligned = |
!screen->get_param(screen, |
PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY); |
caps->buffer_stride_unaligned = |
!screen->get_param(screen, |
PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY); |
caps->velem_src_offset_unaligned = |
!screen->get_param(screen, |
PIPE_CAP_VERTEX_ELEMENT_SRC_OFFSET_4BYTE_ALIGNED_ONLY); |
caps->user_vertex_buffers = |
screen->get_param(screen, PIPE_CAP_USER_VERTEX_BUFFERS); |
} |
struct u_vbuf * |
u_vbuf_create(struct pipe_context *pipe, |
struct u_vbuf_caps *caps, unsigned aux_vertex_buffer_index) |
{ |
struct u_vbuf *mgr = CALLOC_STRUCT(u_vbuf); |
mgr->caps = *caps; |
mgr->aux_vertex_buffer_slot = aux_vertex_buffer_index; |
mgr->pipe = pipe; |
mgr->cso_cache = cso_cache_create(); |
mgr->translate_cache = translate_cache_create(); |
memset(mgr->fallback_vbs, ~0, sizeof(mgr->fallback_vbs)); |
mgr->uploader = u_upload_create(pipe, 1024 * 1024, 4, |
PIPE_BIND_VERTEX_BUFFER); |
return mgr; |
} |
/* u_vbuf uses its own caching for vertex elements, because it needs to keep |
* its own preprocessed state per vertex element CSO. */ |
static struct u_vbuf_elements * |
u_vbuf_set_vertex_elements_internal(struct u_vbuf *mgr, unsigned count, |
const struct pipe_vertex_element *states) |
{ |
struct pipe_context *pipe = mgr->pipe; |
unsigned key_size, hash_key; |
struct cso_hash_iter iter; |
struct u_vbuf_elements *ve; |
struct cso_velems_state velems_state; |
/* need to include the count into the stored state data too. */ |
key_size = sizeof(struct pipe_vertex_element) * count + sizeof(unsigned); |
velems_state.count = count; |
memcpy(velems_state.velems, states, |
sizeof(struct pipe_vertex_element) * count); |
hash_key = cso_construct_key((void*)&velems_state, key_size); |
iter = cso_find_state_template(mgr->cso_cache, hash_key, CSO_VELEMENTS, |
(void*)&velems_state, key_size); |
if (cso_hash_iter_is_null(iter)) { |
struct cso_velements *cso = MALLOC_STRUCT(cso_velements); |
memcpy(&cso->state, &velems_state, key_size); |
cso->data = u_vbuf_create_vertex_elements(mgr, count, states); |
cso->delete_state = (cso_state_callback)u_vbuf_delete_vertex_elements; |
cso->context = (void*)mgr; |
iter = cso_insert_state(mgr->cso_cache, hash_key, CSO_VELEMENTS, cso); |
ve = cso->data; |
} else { |
ve = ((struct cso_velements *)cso_hash_iter_data(iter))->data; |
} |
assert(ve); |
if (ve != mgr->ve) |
pipe->bind_vertex_elements_state(pipe, ve->driver_cso); |
return ve; |
} |
void u_vbuf_set_vertex_elements(struct u_vbuf *mgr, unsigned count, |
const struct pipe_vertex_element *states) |
{ |
mgr->ve = u_vbuf_set_vertex_elements_internal(mgr, count, states); |
} |
void u_vbuf_destroy(struct u_vbuf *mgr) |
{ |
struct pipe_screen *screen = mgr->pipe->screen; |
unsigned i; |
unsigned num_vb = screen->get_shader_param(screen, PIPE_SHADER_VERTEX, |
PIPE_SHADER_CAP_MAX_INPUTS); |
mgr->pipe->set_index_buffer(mgr->pipe, NULL); |
pipe_resource_reference(&mgr->index_buffer.buffer, NULL); |
mgr->pipe->set_vertex_buffers(mgr->pipe, 0, num_vb, NULL); |
for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { |
pipe_resource_reference(&mgr->vertex_buffer[i].buffer, NULL); |
} |
for (i = 0; i < PIPE_MAX_ATTRIBS; i++) { |
pipe_resource_reference(&mgr->real_vertex_buffer[i].buffer, NULL); |
} |
pipe_resource_reference(&mgr->aux_vertex_buffer_saved.buffer, NULL); |
translate_cache_destroy(mgr->translate_cache); |
u_upload_destroy(mgr->uploader); |
cso_cache_delete(mgr->cso_cache); |
FREE(mgr); |
} |
static enum pipe_error |
u_vbuf_translate_buffers(struct u_vbuf *mgr, struct translate_key *key, |
unsigned vb_mask, unsigned out_vb, |
int start_vertex, unsigned num_vertices, |
int start_index, unsigned num_indices, int min_index, |
boolean unroll_indices) |
{ |
struct translate *tr; |
struct pipe_transfer *vb_transfer[PIPE_MAX_ATTRIBS] = {0}; |
struct pipe_resource *out_buffer = NULL; |
uint8_t *out_map; |
unsigned out_offset, mask; |
enum pipe_error err; |
/* Get a translate object. */ |
tr = translate_cache_find(mgr->translate_cache, key); |
/* Map buffers we want to translate. */ |
mask = vb_mask; |
while (mask) { |
struct pipe_vertex_buffer *vb; |
unsigned offset; |
uint8_t *map; |
unsigned i = u_bit_scan(&mask); |
vb = &mgr->vertex_buffer[i]; |
offset = vb->buffer_offset + vb->stride * start_vertex; |
if (vb->user_buffer) { |
map = (uint8_t*)vb->user_buffer + offset; |
} else { |
unsigned size = vb->stride ? num_vertices * vb->stride |
: sizeof(double)*4; |
if (offset+size > vb->buffer->width0) { |
size = vb->buffer->width0 - offset; |
} |
map = pipe_buffer_map_range(mgr->pipe, vb->buffer, offset, size, |
PIPE_TRANSFER_READ, &vb_transfer[i]); |
} |
/* Subtract min_index so that indexing with the index buffer works. */ |
if (unroll_indices) { |
map -= vb->stride * min_index; |
} |
tr->set_buffer(tr, i, map, vb->stride, ~0); |
} |
/* Translate. */ |
if (unroll_indices) { |
struct pipe_index_buffer *ib = &mgr->index_buffer; |
struct pipe_transfer *transfer = NULL; |
unsigned offset = ib->offset + start_index * ib->index_size; |
uint8_t *map; |
assert((ib->buffer || ib->user_buffer) && ib->index_size); |
/* Create and map the output buffer. */ |
err = u_upload_alloc(mgr->uploader, 0, |
key->output_stride * num_indices, |
&out_offset, &out_buffer, |
(void**)&out_map); |
if (err != PIPE_OK) |
return err; |
if (ib->user_buffer) { |
map = (uint8_t*)ib->user_buffer + offset; |
} else { |
map = pipe_buffer_map_range(mgr->pipe, ib->buffer, offset, |
num_indices * ib->index_size, |
PIPE_TRANSFER_READ, &transfer); |
} |
switch (ib->index_size) { |
case 4: |
tr->run_elts(tr, (unsigned*)map, num_indices, 0, 0, out_map); |
break; |
case 2: |
tr->run_elts16(tr, (uint16_t*)map, num_indices, 0, 0, out_map); |
break; |
case 1: |
tr->run_elts8(tr, map, num_indices, 0, 0, out_map); |
break; |
} |
if (transfer) { |
pipe_buffer_unmap(mgr->pipe, transfer); |
} |
} else { |
/* Create and map the output buffer. */ |
err = u_upload_alloc(mgr->uploader, |
key->output_stride * start_vertex, |
key->output_stride * num_vertices, |
&out_offset, &out_buffer, |
(void**)&out_map); |
if (err != PIPE_OK) |
return err; |
out_offset -= key->output_stride * start_vertex; |
tr->run(tr, 0, num_vertices, 0, 0, out_map); |
} |
/* Unmap all buffers. */ |
mask = vb_mask; |
while (mask) { |
unsigned i = u_bit_scan(&mask); |
if (vb_transfer[i]) { |
pipe_buffer_unmap(mgr->pipe, vb_transfer[i]); |
} |
} |
/* Setup the new vertex buffer. */ |
mgr->real_vertex_buffer[out_vb].buffer_offset = out_offset; |
mgr->real_vertex_buffer[out_vb].stride = key->output_stride; |
/* Move the buffer reference. */ |
pipe_resource_reference( |
&mgr->real_vertex_buffer[out_vb].buffer, NULL); |
mgr->real_vertex_buffer[out_vb].buffer = out_buffer; |
return PIPE_OK; |
} |
static boolean |
u_vbuf_translate_find_free_vb_slots(struct u_vbuf *mgr, |
unsigned mask[VB_NUM]) |
{ |
unsigned type; |
unsigned fallback_vbs[VB_NUM]; |
/* Set the bit for each buffer which is incompatible, or isn't set. */ |
uint32_t unused_vb_mask = |
mgr->ve->incompatible_vb_mask_all | mgr->incompatible_vb_mask | |
~mgr->enabled_vb_mask; |
memset(fallback_vbs, ~0, sizeof(fallback_vbs)); |
/* Find free slots for each type if needed. */ |
for (type = 0; type < VB_NUM; type++) { |
if (mask[type]) { |
uint32_t index; |
if (!unused_vb_mask) { |
return FALSE; |
} |
index = ffs(unused_vb_mask) - 1; |
fallback_vbs[type] = index; |
/*printf("found slot=%i for type=%i\n", index, type);*/ |
} |
} |
for (type = 0; type < VB_NUM; type++) { |
if (mask[type]) { |
mgr->dirty_real_vb_mask |= 1 << fallback_vbs[type]; |
} |
} |
memcpy(mgr->fallback_vbs, fallback_vbs, sizeof(fallback_vbs)); |
return TRUE; |
} |
static boolean |
u_vbuf_translate_begin(struct u_vbuf *mgr, |
int start_vertex, unsigned num_vertices, |
int start_instance, unsigned num_instances, |
int start_index, unsigned num_indices, int min_index, |
boolean unroll_indices) |
{ |
unsigned mask[VB_NUM] = {0}; |
struct translate_key key[VB_NUM]; |
unsigned elem_index[VB_NUM][PIPE_MAX_ATTRIBS]; /* ... into key.elements */ |
unsigned i, type; |
unsigned incompatible_vb_mask = mgr->incompatible_vb_mask & |
mgr->ve->used_vb_mask; |
int start[VB_NUM] = { |
start_vertex, /* VERTEX */ |
start_instance, /* INSTANCE */ |
0 /* CONST */ |
}; |
unsigned num[VB_NUM] = { |
num_vertices, /* VERTEX */ |
num_instances, /* INSTANCE */ |
1 /* CONST */ |
}; |
memset(key, 0, sizeof(key)); |
memset(elem_index, ~0, sizeof(elem_index)); |
/* See if there are vertex attribs of each type to translate and |
* which ones. */ |
for (i = 0; i < mgr->ve->count; i++) { |
unsigned vb_index = mgr->ve->ve[i].vertex_buffer_index; |
if (!mgr->vertex_buffer[vb_index].stride) { |
if (!(mgr->ve->incompatible_elem_mask & (1 << i)) && |
!(incompatible_vb_mask & (1 << vb_index))) { |
continue; |
} |
mask[VB_CONST] |= 1 << vb_index; |
} else if (mgr->ve->ve[i].instance_divisor) { |
if (!(mgr->ve->incompatible_elem_mask & (1 << i)) && |
!(incompatible_vb_mask & (1 << vb_index))) { |
continue; |
} |
mask[VB_INSTANCE] |= 1 << vb_index; |
} else { |
if (!unroll_indices && |
!(mgr->ve->incompatible_elem_mask & (1 << i)) && |
!(incompatible_vb_mask & (1 << vb_index))) { |
continue; |
} |
mask[VB_VERTEX] |= 1 << vb_index; |
} |
} |
assert(mask[VB_VERTEX] || mask[VB_INSTANCE] || mask[VB_CONST]); |
/* Find free vertex buffer slots. */ |
if (!u_vbuf_translate_find_free_vb_slots(mgr, mask)) { |
return FALSE; |
} |
/* Initialize the translate keys. */ |
for (i = 0; i < mgr->ve->count; i++) { |
struct translate_key *k; |
struct translate_element *te; |
unsigned bit, vb_index = mgr->ve->ve[i].vertex_buffer_index; |
bit = 1 << vb_index; |
if (!(mgr->ve->incompatible_elem_mask & (1 << i)) && |
!(incompatible_vb_mask & (1 << vb_index)) && |
(!unroll_indices || !(mask[VB_VERTEX] & bit))) { |
continue; |
} |
/* Set type to what we will translate. |
* Whether vertex, instance, or constant attribs. */ |
for (type = 0; type < VB_NUM; type++) { |
if (mask[type] & bit) { |
break; |
} |
} |
assert(type < VB_NUM); |
assert(translate_is_output_format_supported(mgr->ve->native_format[i])); |
/*printf("velem=%i type=%i\n", i, type);*/ |
/* Add the vertex element. */ |
k = &key[type]; |
elem_index[type][i] = k->nr_elements; |
te = &k->element[k->nr_elements]; |
te->type = TRANSLATE_ELEMENT_NORMAL; |
te->instance_divisor = 0; |
te->input_buffer = vb_index; |
te->input_format = mgr->ve->ve[i].src_format; |
te->input_offset = mgr->ve->ve[i].src_offset; |
te->output_format = mgr->ve->native_format[i]; |
te->output_offset = k->output_stride; |
k->output_stride += mgr->ve->native_format_size[i]; |
k->nr_elements++; |
} |
/* Translate buffers. */ |
for (type = 0; type < VB_NUM; type++) { |
if (key[type].nr_elements) { |
enum pipe_error err; |
err = u_vbuf_translate_buffers(mgr, &key[type], mask[type], |
mgr->fallback_vbs[type], |
start[type], num[type], |
start_index, num_indices, min_index, |
unroll_indices && type == VB_VERTEX); |
if (err != PIPE_OK) |
return FALSE; |
/* Fixup the stride for constant attribs. */ |
if (type == VB_CONST) { |
mgr->real_vertex_buffer[mgr->fallback_vbs[VB_CONST]].stride = 0; |
} |
} |
} |
/* Setup new vertex elements. */ |
for (i = 0; i < mgr->ve->count; i++) { |
for (type = 0; type < VB_NUM; type++) { |
if (elem_index[type][i] < key[type].nr_elements) { |
struct translate_element *te = &key[type].element[elem_index[type][i]]; |
mgr->fallback_velems[i].instance_divisor = mgr->ve->ve[i].instance_divisor; |
mgr->fallback_velems[i].src_format = te->output_format; |
mgr->fallback_velems[i].src_offset = te->output_offset; |
mgr->fallback_velems[i].vertex_buffer_index = mgr->fallback_vbs[type]; |
/* elem_index[type][i] can only be set for one type. */ |
assert(type > VB_INSTANCE || elem_index[type+1][i] == ~0); |
assert(type > VB_VERTEX || elem_index[type+2][i] == ~0); |
break; |
} |
} |
/* No translating, just copy the original vertex element over. */ |
if (type == VB_NUM) { |
memcpy(&mgr->fallback_velems[i], &mgr->ve->ve[i], |
sizeof(struct pipe_vertex_element)); |
} |
} |
u_vbuf_set_vertex_elements_internal(mgr, mgr->ve->count, |
mgr->fallback_velems); |
mgr->using_translate = TRUE; |
return TRUE; |
} |
static void u_vbuf_translate_end(struct u_vbuf *mgr) |
{ |
unsigned i; |
/* Restore vertex elements. */ |
mgr->pipe->bind_vertex_elements_state(mgr->pipe, mgr->ve->driver_cso); |
mgr->using_translate = FALSE; |
/* Unreference the now-unused VBOs. */ |
for (i = 0; i < VB_NUM; i++) { |
unsigned vb = mgr->fallback_vbs[i]; |
if (vb != ~0) { |
pipe_resource_reference(&mgr->real_vertex_buffer[vb].buffer, NULL); |
mgr->fallback_vbs[i] = ~0; |
/* This will cause the buffer to be unbound in the driver later. */ |
mgr->dirty_real_vb_mask |= 1 << vb; |
} |
} |
} |
#define FORMAT_REPLACE(what, withwhat) \ |
case PIPE_FORMAT_##what: format = PIPE_FORMAT_##withwhat; break |
static void * |
u_vbuf_create_vertex_elements(struct u_vbuf *mgr, unsigned count, |
const struct pipe_vertex_element *attribs) |
{ |
struct pipe_context *pipe = mgr->pipe; |
unsigned i; |
struct pipe_vertex_element driver_attribs[PIPE_MAX_ATTRIBS]; |
struct u_vbuf_elements *ve = CALLOC_STRUCT(u_vbuf_elements); |
uint32_t used_buffers = 0; |
ve->count = count; |
memcpy(ve->ve, attribs, sizeof(struct pipe_vertex_element) * count); |
memcpy(driver_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; |
ve->src_format_size[i] = util_format_get_blocksize(format); |
used_buffers |= 1 << ve->ve[i].vertex_buffer_index; |
if (!ve->ve[i].instance_divisor) { |
ve->noninstance_vb_mask_any |= 1 << ve->ve[i].vertex_buffer_index; |
} |
/* 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:; |
} |
} |
driver_attribs[i].src_format = format; |
ve->native_format[i] = format; |
ve->native_format_size[i] = |
util_format_get_blocksize(ve->native_format[i]); |
if (ve->ve[i].src_format != format || |
(!mgr->caps.velem_src_offset_unaligned && |
ve->ve[i].src_offset % 4 != 0)) { |
ve->incompatible_elem_mask |= 1 << i; |
ve->incompatible_vb_mask_any |= 1 << ve->ve[i].vertex_buffer_index; |
} else { |
ve->compatible_vb_mask_any |= 1 << ve->ve[i].vertex_buffer_index; |
} |
} |
ve->used_vb_mask = used_buffers; |
ve->compatible_vb_mask_all = ~ve->incompatible_vb_mask_any & used_buffers; |
ve->incompatible_vb_mask_all = ~ve->compatible_vb_mask_any & used_buffers; |
/* Align the formats to the size of DWORD if needed. */ |
if (!mgr->caps.velem_src_offset_unaligned) { |
for (i = 0; i < count; i++) { |
ve->native_format_size[i] = align(ve->native_format_size[i], 4); |
} |
} |
ve->driver_cso = |
pipe->create_vertex_elements_state(pipe, count, driver_attribs); |
return ve; |
} |
static void u_vbuf_delete_vertex_elements(struct u_vbuf *mgr, void *cso) |
{ |
struct pipe_context *pipe = mgr->pipe; |
struct u_vbuf_elements *ve = cso; |
pipe->delete_vertex_elements_state(pipe, ve->driver_cso); |
FREE(ve); |
} |
void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr, |
unsigned start_slot, unsigned count, |
const struct pipe_vertex_buffer *bufs) |
{ |
unsigned i; |
/* which buffers are enabled */ |
uint32_t enabled_vb_mask = 0; |
/* which buffers are in user memory */ |
uint32_t user_vb_mask = 0; |
/* which buffers are incompatible with the driver */ |
uint32_t incompatible_vb_mask = 0; |
/* which buffers have a non-zero stride */ |
uint32_t nonzero_stride_vb_mask = 0; |
uint32_t mask = ~(((1ull << count) - 1) << start_slot); |
/* Zero out the bits we are going to rewrite completely. */ |
mgr->user_vb_mask &= mask; |
mgr->incompatible_vb_mask &= mask; |
mgr->nonzero_stride_vb_mask &= mask; |
mgr->enabled_vb_mask &= mask; |
if (!bufs) { |
struct pipe_context *pipe = mgr->pipe; |
/* Unbind. */ |
mgr->dirty_real_vb_mask &= mask; |
for (i = 0; i < count; i++) { |
unsigned dst_index = start_slot + i; |
pipe_resource_reference(&mgr->vertex_buffer[dst_index].buffer, NULL); |
pipe_resource_reference(&mgr->real_vertex_buffer[dst_index].buffer, |
NULL); |
} |
pipe->set_vertex_buffers(pipe, start_slot, count, NULL); |
return; |
} |
for (i = 0; i < count; i++) { |
unsigned dst_index = start_slot + i; |
const struct pipe_vertex_buffer *vb = &bufs[i]; |
struct pipe_vertex_buffer *orig_vb = &mgr->vertex_buffer[dst_index]; |
struct pipe_vertex_buffer *real_vb = &mgr->real_vertex_buffer[dst_index]; |
if (!vb->buffer && !vb->user_buffer) { |
pipe_resource_reference(&orig_vb->buffer, NULL); |
pipe_resource_reference(&real_vb->buffer, NULL); |
real_vb->user_buffer = NULL; |
continue; |
} |
pipe_resource_reference(&orig_vb->buffer, vb->buffer); |
orig_vb->user_buffer = vb->user_buffer; |
real_vb->buffer_offset = orig_vb->buffer_offset = vb->buffer_offset; |
real_vb->stride = orig_vb->stride = vb->stride; |
if (vb->stride) { |
nonzero_stride_vb_mask |= 1 << dst_index; |
} |
enabled_vb_mask |= 1 << dst_index; |
if ((!mgr->caps.buffer_offset_unaligned && vb->buffer_offset % 4 != 0) || |
(!mgr->caps.buffer_stride_unaligned && vb->stride % 4 != 0)) { |
incompatible_vb_mask |= 1 << dst_index; |
pipe_resource_reference(&real_vb->buffer, NULL); |
continue; |
} |
if (!mgr->caps.user_vertex_buffers && vb->user_buffer) { |
user_vb_mask |= 1 << dst_index; |
pipe_resource_reference(&real_vb->buffer, NULL); |
continue; |
} |
pipe_resource_reference(&real_vb->buffer, vb->buffer); |
real_vb->user_buffer = vb->user_buffer; |
} |
mgr->user_vb_mask |= user_vb_mask; |
mgr->incompatible_vb_mask |= incompatible_vb_mask; |
mgr->nonzero_stride_vb_mask |= nonzero_stride_vb_mask; |
mgr->enabled_vb_mask |= enabled_vb_mask; |
/* All changed buffers are marked as dirty, even the NULL ones, |
* which will cause the NULL buffers to be unbound in the driver later. */ |
mgr->dirty_real_vb_mask |= ~mask; |
} |
void u_vbuf_set_index_buffer(struct u_vbuf *mgr, |
const struct pipe_index_buffer *ib) |
{ |
struct pipe_context *pipe = mgr->pipe; |
if (ib) { |
assert(ib->offset % ib->index_size == 0); |
pipe_resource_reference(&mgr->index_buffer.buffer, ib->buffer); |
memcpy(&mgr->index_buffer, ib, sizeof(*ib)); |
} else { |
pipe_resource_reference(&mgr->index_buffer.buffer, NULL); |
} |
pipe->set_index_buffer(pipe, ib); |
} |
static enum pipe_error |
u_vbuf_upload_buffers(struct u_vbuf *mgr, |
int start_vertex, unsigned num_vertices, |
int start_instance, unsigned num_instances) |
{ |
unsigned i; |
unsigned nr_velems = mgr->ve->count; |
struct pipe_vertex_element *velems = |
mgr->using_translate ? mgr->fallback_velems : mgr->ve->ve; |
unsigned start_offset[PIPE_MAX_ATTRIBS]; |
unsigned end_offset[PIPE_MAX_ATTRIBS]; |
uint32_t buffer_mask = 0; |
/* Determine how much data needs to be uploaded. */ |
for (i = 0; i < nr_velems; i++) { |
struct pipe_vertex_element *velem = &velems[i]; |
unsigned index = velem->vertex_buffer_index; |
struct pipe_vertex_buffer *vb = &mgr->vertex_buffer[index]; |
unsigned instance_div, first, size, index_bit; |
/* Skip the buffers generated by translate. */ |
if (index == mgr->fallback_vbs[VB_VERTEX] || |
index == mgr->fallback_vbs[VB_INSTANCE] || |
index == mgr->fallback_vbs[VB_CONST]) { |
continue; |
} |
if (!vb->user_buffer) { |
continue; |
} |
instance_div = velem->instance_divisor; |
first = vb->buffer_offset + velem->src_offset; |
if (!vb->stride) { |
/* Constant attrib. */ |
size = mgr->ve->src_format_size[i]; |
} else if (instance_div) { |
/* Per-instance attrib. */ |
unsigned count = (num_instances + instance_div - 1) / instance_div; |
first += vb->stride * start_instance; |
size = vb->stride * (count - 1) + mgr->ve->src_format_size[i]; |
} else { |
/* Per-vertex attrib. */ |
first += vb->stride * start_vertex; |
size = vb->stride * (num_vertices - 1) + mgr->ve->src_format_size[i]; |
} |
index_bit = 1 << index; |
/* Update offsets. */ |
if (!(buffer_mask & index_bit)) { |
start_offset[index] = first; |
end_offset[index] = first + size; |
} else { |
if (first < start_offset[index]) |
start_offset[index] = first; |
if (first + size > end_offset[index]) |
end_offset[index] = first + size; |
} |
buffer_mask |= index_bit; |
} |
/* Upload buffers. */ |
while (buffer_mask) { |
unsigned start, end; |
struct pipe_vertex_buffer *real_vb; |
const uint8_t *ptr; |
enum pipe_error err; |
i = u_bit_scan(&buffer_mask); |
start = start_offset[i]; |
end = end_offset[i]; |
assert(start < end); |
real_vb = &mgr->real_vertex_buffer[i]; |
ptr = mgr->vertex_buffer[i].user_buffer; |
err = u_upload_data(mgr->uploader, start, end - start, ptr + start, |
&real_vb->buffer_offset, &real_vb->buffer); |
if (err != PIPE_OK) |
return err; |
real_vb->buffer_offset -= start; |
} |
return PIPE_OK; |
} |
static boolean u_vbuf_need_minmax_index(struct u_vbuf *mgr) |
{ |
/* See if there are any per-vertex attribs which will be uploaded or |
* translated. Use bitmasks to get the info instead of looping over vertex |
* elements. */ |
return (mgr->ve->used_vb_mask & |
((mgr->user_vb_mask | mgr->incompatible_vb_mask | |
mgr->ve->incompatible_vb_mask_any) & |
mgr->ve->noninstance_vb_mask_any & mgr->nonzero_stride_vb_mask)) != 0; |
} |
static boolean u_vbuf_mapping_vertex_buffer_blocks(struct u_vbuf *mgr) |
{ |
/* Return true if there are hw buffers which don't need to be translated. |
* |
* We could query whether each buffer is busy, but that would |
* be way more costly than this. */ |
return (mgr->ve->used_vb_mask & |
(~mgr->user_vb_mask & ~mgr->incompatible_vb_mask & |
mgr->ve->compatible_vb_mask_all & mgr->ve->noninstance_vb_mask_any & |
mgr->nonzero_stride_vb_mask)) != 0; |
} |
static void u_vbuf_get_minmax_index(struct pipe_context *pipe, |
struct pipe_index_buffer *ib, |
const struct pipe_draw_info *info, |
int *out_min_index, |
int *out_max_index) |
{ |
struct pipe_transfer *transfer = NULL; |
const void *indices; |
unsigned i; |
unsigned restart_index = info->restart_index; |
if (ib->user_buffer) { |
indices = (uint8_t*)ib->user_buffer + |
ib->offset + info->start * ib->index_size; |
} else { |
indices = pipe_buffer_map_range(pipe, ib->buffer, |
ib->offset + info->start * ib->index_size, |
info->count * ib->index_size, |
PIPE_TRANSFER_READ, &transfer); |
} |
switch (ib->index_size) { |
case 4: { |
const unsigned *ui_indices = (const unsigned*)indices; |
unsigned max_ui = 0; |
unsigned min_ui = ~0U; |
if (info->primitive_restart) { |
for (i = 0; i < info->count; i++) { |
if (ui_indices[i] != restart_index) { |
if (ui_indices[i] > max_ui) max_ui = ui_indices[i]; |
if (ui_indices[i] < min_ui) min_ui = ui_indices[i]; |
} |
} |
} |
else { |
for (i = 0; i < info->count; i++) { |
if (ui_indices[i] > max_ui) max_ui = ui_indices[i]; |
if (ui_indices[i] < min_ui) min_ui = ui_indices[i]; |
} |
} |
*out_min_index = min_ui; |
*out_max_index = max_ui; |
break; |
} |
case 2: { |
const unsigned short *us_indices = (const unsigned short*)indices; |
unsigned max_us = 0; |
unsigned min_us = ~0U; |
if (info->primitive_restart) { |
for (i = 0; i < info->count; i++) { |
if (us_indices[i] != restart_index) { |
if (us_indices[i] > max_us) max_us = us_indices[i]; |
if (us_indices[i] < min_us) min_us = us_indices[i]; |
} |
} |
} |
else { |
for (i = 0; i < info->count; i++) { |
if (us_indices[i] > max_us) max_us = us_indices[i]; |
if (us_indices[i] < min_us) min_us = us_indices[i]; |
} |
} |
*out_min_index = min_us; |
*out_max_index = max_us; |
break; |
} |
case 1: { |
const unsigned char *ub_indices = (const unsigned char*)indices; |
unsigned max_ub = 0; |
unsigned min_ub = ~0U; |
if (info->primitive_restart) { |
for (i = 0; i < info->count; i++) { |
if (ub_indices[i] != restart_index) { |
if (ub_indices[i] > max_ub) max_ub = ub_indices[i]; |
if (ub_indices[i] < min_ub) min_ub = ub_indices[i]; |
} |
} |
} |
else { |
for (i = 0; i < info->count; i++) { |
if (ub_indices[i] > max_ub) max_ub = ub_indices[i]; |
if (ub_indices[i] < min_ub) min_ub = ub_indices[i]; |
} |
} |
*out_min_index = min_ub; |
*out_max_index = max_ub; |
break; |
} |
default: |
assert(0); |
*out_min_index = 0; |
*out_max_index = 0; |
} |
if (transfer) { |
pipe_buffer_unmap(pipe, transfer); |
} |
} |
static void u_vbuf_set_driver_vertex_buffers(struct u_vbuf *mgr) |
{ |
struct pipe_context *pipe = mgr->pipe; |
unsigned start_slot, count; |
start_slot = ffs(mgr->dirty_real_vb_mask) - 1; |
count = util_last_bit(mgr->dirty_real_vb_mask >> start_slot); |
pipe->set_vertex_buffers(pipe, start_slot, count, |
mgr->real_vertex_buffer + start_slot); |
mgr->dirty_real_vb_mask = 0; |
} |
void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info) |
{ |
struct pipe_context *pipe = mgr->pipe; |
int start_vertex, min_index; |
unsigned num_vertices; |
boolean unroll_indices = FALSE; |
uint32_t used_vb_mask = mgr->ve->used_vb_mask; |
uint32_t user_vb_mask = mgr->user_vb_mask & used_vb_mask; |
uint32_t incompatible_vb_mask = mgr->incompatible_vb_mask & used_vb_mask; |
/* Normal draw. No fallback and no user buffers. */ |
if (!incompatible_vb_mask && |
!mgr->ve->incompatible_elem_mask && |
!user_vb_mask) { |
/* Set vertex buffers if needed. */ |
if (mgr->dirty_real_vb_mask & used_vb_mask) { |
u_vbuf_set_driver_vertex_buffers(mgr); |
} |
pipe->draw_vbo(pipe, info); |
return; |
} |
if (info->indexed) { |
/* See if anything needs to be done for per-vertex attribs. */ |
if (u_vbuf_need_minmax_index(mgr)) { |
int max_index; |
if (info->max_index != ~0) { |
min_index = info->min_index; |
max_index = info->max_index; |
} else { |
u_vbuf_get_minmax_index(mgr->pipe, &mgr->index_buffer, info, |
&min_index, &max_index); |
} |
assert(min_index <= max_index); |
start_vertex = min_index + info->index_bias; |
num_vertices = max_index + 1 - min_index; |
/* Primitive restart doesn't work when unrolling indices. |
* We would have to break this drawing operation into several ones. */ |
/* Use some heuristic to see if unrolling indices improves |
* performance. */ |
if (!info->primitive_restart && |
num_vertices > info->count*2 && |
num_vertices-info->count > 32 && |
!u_vbuf_mapping_vertex_buffer_blocks(mgr)) { |
/*printf("num_vertices=%i count=%i\n", num_vertices, info->count);*/ |
unroll_indices = TRUE; |
user_vb_mask &= ~(mgr->nonzero_stride_vb_mask & |
mgr->ve->noninstance_vb_mask_any); |
} |
} else { |
/* Nothing to do for per-vertex attribs. */ |
start_vertex = 0; |
num_vertices = 0; |
min_index = 0; |
} |
} else { |
start_vertex = info->start; |
num_vertices = info->count; |
min_index = 0; |
} |
/* Translate vertices with non-native layouts or formats. */ |
if (unroll_indices || |
incompatible_vb_mask || |
mgr->ve->incompatible_elem_mask) { |
if (!u_vbuf_translate_begin(mgr, start_vertex, num_vertices, |
info->start_instance, info->instance_count, |
info->start, info->count, min_index, |
unroll_indices)) { |
debug_warn_once("u_vbuf_translate_begin() failed"); |
return; |
} |
user_vb_mask &= ~(incompatible_vb_mask | |
mgr->ve->incompatible_vb_mask_all); |
} |
/* Upload user buffers. */ |
if (user_vb_mask) { |
if (u_vbuf_upload_buffers(mgr, start_vertex, num_vertices, |
info->start_instance, |
info->instance_count) != PIPE_OK) { |
debug_warn_once("u_vbuf_upload_buffers() failed"); |
return; |
} |
mgr->dirty_real_vb_mask |= user_vb_mask; |
} |
/* |
if (unroll_indices) { |
printf("unrolling indices: start_vertex = %i, num_vertices = %i\n", |
start_vertex, num_vertices); |
util_dump_draw_info(stdout, info); |
printf("\n"); |
} |
unsigned i; |
for (i = 0; i < mgr->nr_vertex_buffers; i++) { |
printf("input %i: ", i); |
util_dump_vertex_buffer(stdout, mgr->vertex_buffer+i); |
printf("\n"); |
} |
for (i = 0; i < mgr->nr_real_vertex_buffers; i++) { |
printf("real %i: ", i); |
util_dump_vertex_buffer(stdout, mgr->real_vertex_buffer+i); |
printf("\n"); |
} |
*/ |
u_upload_unmap(mgr->uploader); |
u_vbuf_set_driver_vertex_buffers(mgr); |
if (unlikely(unroll_indices)) { |
struct pipe_draw_info new_info = *info; |
new_info.indexed = FALSE; |
new_info.index_bias = 0; |
new_info.min_index = 0; |
new_info.max_index = info->count - 1; |
new_info.start = 0; |
pipe->draw_vbo(pipe, &new_info); |
} else { |
pipe->draw_vbo(pipe, info); |
} |
if (mgr->using_translate) { |
u_vbuf_translate_end(mgr); |
} |
} |
void u_vbuf_save_vertex_elements(struct u_vbuf *mgr) |
{ |
assert(!mgr->ve_saved); |
mgr->ve_saved = mgr->ve; |
} |
void u_vbuf_restore_vertex_elements(struct u_vbuf *mgr) |
{ |
if (mgr->ve != mgr->ve_saved) { |
struct pipe_context *pipe = mgr->pipe; |
mgr->ve = mgr->ve_saved; |
pipe->bind_vertex_elements_state(pipe, |
mgr->ve ? mgr->ve->driver_cso : NULL); |
} |
mgr->ve_saved = NULL; |
} |
void u_vbuf_save_aux_vertex_buffer_slot(struct u_vbuf *mgr) |
{ |
struct pipe_vertex_buffer *vb = |
&mgr->vertex_buffer[mgr->aux_vertex_buffer_slot]; |
pipe_resource_reference(&mgr->aux_vertex_buffer_saved.buffer, vb->buffer); |
memcpy(&mgr->aux_vertex_buffer_saved, vb, sizeof(*vb)); |
} |
void u_vbuf_restore_aux_vertex_buffer_slot(struct u_vbuf *mgr) |
{ |
u_vbuf_set_vertex_buffers(mgr, mgr->aux_vertex_buffer_slot, 1, |
&mgr->aux_vertex_buffer_saved); |
pipe_resource_reference(&mgr->aux_vertex_buffer_saved.buffer, NULL); |
} |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_vbuf.h |
---|
0,0 → 1,87 |
/************************************************************************** |
* |
* Copyright 2011 Marek Olšák <maraeo@gmail.com> |
* 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_H |
#define U_VBUF_H |
/* This module takes care of user buffer uploads and vertex format fallbacks. |
* It's designed for the drivers which don't want to use the Draw module. |
* There is a more detailed description at the beginning of the .c file. |
*/ |
#include "pipe/p_context.h" |
#include "pipe/p_state.h" |
struct cso_context; |
struct u_vbuf; |
/* 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 4-byte-aligned. */ |
/* TRUE if hardware supports it. */ |
unsigned buffer_offset_unaligned:1; |
unsigned buffer_stride_unaligned:1; |
unsigned velem_src_offset_unaligned:1; |
/* Whether the driver supports user vertex buffers. */ |
unsigned user_vertex_buffers:1; |
}; |
void u_vbuf_get_caps(struct pipe_screen *screen, struct u_vbuf_caps *caps); |
struct u_vbuf * |
u_vbuf_create(struct pipe_context *pipe, |
struct u_vbuf_caps *caps, unsigned aux_vertex_buffer_index); |
void u_vbuf_destroy(struct u_vbuf *mgr); |
/* State and draw functions. */ |
void u_vbuf_set_vertex_elements(struct u_vbuf *mgr, unsigned count, |
const struct pipe_vertex_element *states); |
void u_vbuf_set_vertex_buffers(struct u_vbuf *mgr, |
unsigned start_slot, unsigned count, |
const struct pipe_vertex_buffer *bufs); |
void u_vbuf_set_index_buffer(struct u_vbuf *mgr, |
const struct pipe_index_buffer *ib); |
void u_vbuf_draw_vbo(struct u_vbuf *mgr, const struct pipe_draw_info *info); |
/* Save/restore functionality. */ |
void u_vbuf_save_vertex_elements(struct u_vbuf *mgr); |
void u_vbuf_restore_vertex_elements(struct u_vbuf *mgr); |
void u_vbuf_save_aux_vertex_buffer_slot(struct u_vbuf *mgr); |
void u_vbuf_restore_aux_vertex_buffer_slot(struct u_vbuf *mgr); |
#endif |
/contrib/sdk/sources/Mesa/src/gallium/auxiliary/util/u_video.h |
---|
0,0 → 1,75 |
/************************************************************************** |
* |
* Copyright 2009 Younes Manton. |
* 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 TUNGSTEN GRAPHICS 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_VIDEO_H |
#define U_VIDEO_H |
#ifdef __cplusplus |
extern "C" { |
#endif |
#include "pipe/p_defines.h" |
#include "pipe/p_video_enums.h" |
/* u_reduce_video_profile() needs these */ |
#include "pipe/p_compiler.h" |
#include "util/u_debug.h" |
static INLINE enum pipe_video_codec |
u_reduce_video_profile(enum pipe_video_profile profile) |
{ |
switch (profile) |
{ |
case PIPE_VIDEO_PROFILE_MPEG1: |
case PIPE_VIDEO_PROFILE_MPEG2_SIMPLE: |
case PIPE_VIDEO_PROFILE_MPEG2_MAIN: |
return PIPE_VIDEO_CODEC_MPEG12; |
case PIPE_VIDEO_PROFILE_MPEG4_SIMPLE: |
case PIPE_VIDEO_PROFILE_MPEG4_ADVANCED_SIMPLE: |
return PIPE_VIDEO_CODEC_MPEG4; |
case PIPE_VIDEO_PROFILE_VC1_SIMPLE: |
case PIPE_VIDEO_PROFILE_VC1_MAIN: |
case PIPE_VIDEO_PROFILE_VC1_ADVANCED: |
return PIPE_VIDEO_CODEC_VC1; |
case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE: |
case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN: |
case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH: |
return PIPE_VIDEO_CODEC_MPEG4_AVC; |
default: |
return PIPE_VIDEO_CODEC_UNKNOWN; |
} |
} |
#ifdef __cplusplus |
} |
#endif |
#endif /* U_VIDEO_H */ |