Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 4357 → Rev 4358

/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 '};'
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 '}'
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 '}'
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 '}'
print
 
 
def is_format_hand_written(format):
return format.layout in ('s3tc', 'rgtc', 'etc', 'subsampled', 'other') or format.colorspace == ZS
 
 
def generate(formats):
print
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"'
print
 
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 '};'
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 '};'
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
print '};'
print
 
 
def main():
print '/* This file is autogenerated by u_format_srgb.py. Do not edit directly. */'
print
# This will print the copyright message on the top of this file
print CopyRight.strip()
print
print '#include "u_format_srgb.h"'
print
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. */'
print
# This will print the copyright message on the top of this file
print CopyRight.strip()
print
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"'
print
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
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
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 "}"
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 */