Initial commit

This commit is contained in:
alexpete
2021-03-05 11:26:34 -08:00
commit a10351f38d
27091 changed files with 5521199 additions and 0 deletions
@@ -0,0 +1,219 @@
// Modifications copyright Amazon.com, Inc. or its affiliates
// Modifications copyright Crytek GmbH
#include "internal_includes/toGLSLInstruction.h"
#include "internal_includes/toGLSLOperand.h"
#include "internal_includes/languages.h"
#include "bstrlib.h"
#include "stdio.h"
#include "internal_includes/debug.h"
#include "internal_includes/hlslcc_malloc.h"
#include "amazon_changes.h"
#if defined(__clang__)
#pragma clang diagnostic ignored "-Wpointer-sign"
#endif
extern void AddIndentation(HLSLCrossCompilerContext* psContext);
// These are .c files, so no C++ or C++11 for us :(
#define MAX_VARIABLE_LENGTH 16
// This struct is used to keep track of each valid occurance of xxxBitsToxxx(variable) and store all relevant information for fixing that instance
typedef struct ShaderCastLocation
{
char tempVariableName[MAX_VARIABLE_LENGTH];
char replacementVariableName[MAX_VARIABLE_LENGTH];
unsigned int castType;
// Since we have no stl, here's our list
struct ShaderCastLocation* next;
} ShaderCastLocation;
// Structure used to prebuild the list of all functions that need to be replaced.
typedef struct ShaderCastType
{
const char* functionName;
unsigned int castType;
const char* variableTypeName; // String for the variable type used when declaring a temporary variable to replace the source temp vector
} ShaderCastType;
enum ShaderCasts
{
CAST_UINTBITSTOFLOAT,
CAST_INTBITSTOFLOAT,
CAST_FLOATBITSTOUINT,
CAST_FLOATBITSTOINT,
CAST_NUMCASTS
};
// NOTICE: Order is important here because intBitsToFloat is a substring of uintBitsToFloat, so do not change the ordering here!
static const ShaderCastType s_castFunctions[CAST_NUMCASTS] =
{
{ "uintBitsToFloat", CAST_UINTBITSTOFLOAT, "uvec4" },
{ "intBitsToFloat", CAST_INTBITSTOFLOAT, "ivec4" },
{ "floatBitsToUint", CAST_FLOATBITSTOUINT, "vec4" },
{ "floatBitsToInt", CAST_FLOATBITSTOINT, "vec4" }
};
int IsValidUseCase( char* variableStart, char* outVariableName, ShaderCastLocation* foundShaderCastsHead, int currentType )
{
// Cases we have to replace (this is very strict in definition):
// 1) floatBitsToInt(Temp2)
// 2) floatBitsToInt(Temp2.x)
// 3) floatBitsToInt(Temp[0])
// 4) floatBitsToInt(Temp[0].x)
// Cases we do not have to replace:
// 1) floatBitsToInt(vec4(Temp2))
// 2) floatBitsToInt(Output0.x != 0.0f ? 1.0f : 0.0f)
// 3) Any other version that evaluates an expression within the ()
if ( strncmp(variableStart, "Temp", 4) != 0 )
return 0;
unsigned int lengthOfVariable = 4; // Start at 4 for temp
while ( 1 )
{
char val = *(variableStart + lengthOfVariable);
// If alphanumeric or [] (array), we have a valid variable name
if ( isalnum( val ) || (val == '[') || (val == ']') )
{
lengthOfVariable++;
}
else if ( (val == ')') || (val == '.') )
{
// Found end of variable
break;
}
else
{
// Found something unexpected, so abort
return 0;
}
}
ASSERT( lengthOfVariable < MAX_VARIABLE_LENGTH );
// Now ensure that no duplicates of this declaration already exist
ShaderCastLocation* currentLink = foundShaderCastsHead;
while ( currentLink )
{
// If we have the same type and the same name
if ( (currentType == currentLink->castType) && (strncmp(variableStart, currentLink->tempVariableName, lengthOfVariable) == 0) )
return 0; // Do not add because an entry already exists for this variable and this cast function
// Hmm...I guess this scenario is possible, but it has not shown up in any shaders.
// The only time we could ever hit this is if the same line casts a float to both an int and uint in separate calls
// Seems highly unlikely, so let's just assert for now and fix it if we have to.
if ( strncmp(variableStart, currentLink->tempVariableName, lengthOfVariable) == 0 )
{
// TODO: Implement this case where we cast the same variable to multiple types on the same line of GLSL
ASSERT(0);
}
currentLink = currentLink->next;
}
// We found a unique instance, so store it
strncpy( outVariableName, variableStart, lengthOfVariable );
return 1;
}
void ModifyLineForQualcommReinterpretCastBug( HLSLCrossCompilerContext* psContext, bstring* originalString, bstring* overloadString )
{
unsigned int numFoundCasts = 0;
ShaderCastLocation* foundShaderCastsHead = NULL;
ShaderCastLocation* currentShaderCasts = NULL;
// Find all occurances of the *BitsTo* functions
// Note that this would be cleaner, but 'intBitsToFloat' is a substring of 'uintBitsToFloat' so parsing order is important here.
char* parsingString = bdataofs(*overloadString, 0);
while ( parsingString )
{
char* result = NULL;
for ( int index=0; index<CAST_NUMCASTS; ++index )
{
result = strstr( parsingString, s_castFunctions[index].functionName );
if ( result != NULL )
{
// Now determine if this is a case that requires a workaround
char* variableStart = result + strlen( s_castFunctions[index].functionName ) + 1; // Add the function name + first parenthesis
char tempVariableName[MAX_VARIABLE_LENGTH];
memset( tempVariableName, 0, MAX_VARIABLE_LENGTH );
// Now the next word must be Temp, or this is not a valid case
if ( IsValidUseCase( variableStart, tempVariableName, foundShaderCastsHead, index ) )
{
// Now store the information about this cast. Allocate a new link in the list.
if ( !foundShaderCastsHead )
{
foundShaderCastsHead = (ShaderCastLocation*)hlslcc_malloc( sizeof(ShaderCastLocation) );
memset( foundShaderCastsHead, 0x0, sizeof(ShaderCastLocation) );
currentShaderCasts = foundShaderCastsHead;
}
else
{
ASSERT( !currentShaderCasts->next );
currentShaderCasts->next = (ShaderCastLocation*)hlslcc_malloc( sizeof(ShaderCastLocation) );
memset( currentShaderCasts->next, 0x0, sizeof(ShaderCastLocation) );
currentShaderCasts = currentShaderCasts->next;
}
currentShaderCasts->castType = index;
strcpy( currentShaderCasts->tempVariableName, tempVariableName );
numFoundCasts++;
}
result += strlen( s_castFunctions[index].functionName );
// Break out of the loop because we have to advance the search string and start over with uintBitsToFloat again due to the problem with intBitsToFloat being a substring
break;
}
}
parsingString = result;
}
// If we have found no casts, then append the line to the primary string
if ( numFoundCasts == 0 )
{
bconcat( *originalString, *overloadString );
return;
}
// Now we start creating our temporary variables to workaround the crash
currentShaderCasts = foundShaderCastsHead;
// NOTE: We want a count of all variables processed for this entire shader. This could be fancier...
static unsigned int currentVariableIndex = 0;
while ( currentShaderCasts )
{
// Generate new variable name
sprintf( currentShaderCasts->replacementVariableName, "LYTemp%i", currentVariableIndex );
// Write out the new variable name declaration and initialize it
AddIndentation( psContext );
bformata( *originalString, "%s %s=%s;\n", s_castFunctions[currentShaderCasts->castType].variableTypeName, currentShaderCasts->replacementVariableName, currentShaderCasts->tempVariableName );
// Now replace all instances of the variable in question with the new variable name.
// Note: We can't do a breplace on the temp variable name because the variable can still be legally used without a reinterpret cast in that line.
// Do a full replace on the xxBitsToxx(TempVar) here
bstring tempVarName = bformat( "%s(%s)", s_castFunctions[currentShaderCasts->castType].functionName, currentShaderCasts->tempVariableName );
bstring replacementVarName = bformat( "%s(%s)", s_castFunctions[currentShaderCasts->castType].functionName, currentShaderCasts->replacementVariableName );
bfindreplace( *overloadString, tempVarName, replacementVarName, 0 );
// Cleanup bstrings allocated from bformat
bdestroy( tempVarName );
bdestroy( replacementVarName );
currentVariableIndex++;
currentShaderCasts = currentShaderCasts->next;
}
// Now append our modified string to the full shader file
bconcat( *originalString, *overloadString );
}
@@ -0,0 +1,20 @@
/*
* This source file is part of the bstring string library. This code was
* written by Paul Hsieh in 2002-2010, and is covered by either the 3-clause
* BSD open source license or GPL v2.0. Refer to the accompanying documentation
* for details on usage and license.
*/
// Modifications copyright Amazon.com, Inc. or its affiliates
/*
* bsafe.c
*
* This is an optional module that can be used to help enforce a safety
* standard based on pervasive usage of bstrlib. This file is not necessarily
* portable, however, it has been tested to work correctly with Intel's C/C++
* compiler, WATCOM C/C++ v11.x and Microsoft Visual C++.
*/
#include <stdio.h>
#include <stdlib.h>
#include "bsafe.h"
@@ -0,0 +1,45 @@
/*
* This source file is part of the bstring string library. This code was
* written by Paul Hsieh in 2002-2010, and is covered by either the 3-clause
* BSD open source license or GPL v2.0. Refer to the accompanying documentation
* for details on usage and license.
*/
// Modifications copyright Amazon.com, Inc. or its affiliates
/*
* bsafe.h
*
* This is an optional module that can be used to help enforce a safety
* standard based on pervasive usage of bstrlib. This file is not necessarily
* portable, however, it has been tested to work correctly with Intel's C/C++
* compiler, WATCOM C/C++ v11.x and Microsoft Visual C++.
*/
#ifndef BSTRLIB_BSAFE_INCLUDE
#define BSTRLIB_BSAFE_INCLUDE
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(__GNUC__) && !defined(__clang__)
#if !defined (__GNUC__) && (!defined(_MSC_VER) || (_MSC_VER <= 1310))
/* This is caught in the linker, so its not necessary for gcc. */
extern char * (gets) (char * buf);
#endif
extern char * (strncpy) (char *dst, const char *src, size_t n);
extern char * (strncat) (char *dst, const char *src, size_t n);
extern char * (strtok) (char *s1, const char *s2);
extern char * (strdup) (const char *s);
#undef strcpy
#undef strcat
#define strcpy(a,b) bsafe_strcpy(a,b)
#define strcat(a,b) bsafe_strcat(a,b)
#endif
#ifdef __cplusplus
}
#endif
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,113 @@
/*
* This source file is part of the bstring string library. This code was
* written by Paul Hsieh in 2002-2010, and is covered by either the 3-clause
* BSD open source license or GPL v2.0. Refer to the accompanying documentation
* for details on usage and license.
*/
// Modifications copyright Amazon.com, Inc. or its affiliates
/*
* bstraux.h
*
* This file is not a necessary part of the core bstring library itself, but
* is just an auxilliary module which includes miscellaneous or trivial
* functions.
*/
#ifndef BSTRAUX_INCLUDE
#define BSTRAUX_INCLUDE
#include <time.h>
#include "bstrlib.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Safety mechanisms */
#define bstrDeclare(b) bstring (b) = NULL;
#define bstrFree(b) {if ((b) != NULL && (b)->slen >= 0 && (b)->mlen >= (b)->slen) { bdestroy (b); (b) = NULL; }}
/* Backward compatibilty with previous versions of Bstrlib */
#define bAssign(a,b) ((bassign)((a), (b)))
#define bSubs(b,pos,len,a,c) ((breplace)((b),(pos),(len),(a),(unsigned char)(c)))
#define bStrchr(b,c) ((bstrchr)((b), (c)))
#define bStrchrFast(b,c) ((bstrchr)((b), (c)))
#define bCatCstr(b,s) ((bcatcstr)((b), (s)))
#define bCatBlk(b,s,len) ((bcatblk)((b),(s),(len)))
#define bCatStatic(b,s) bCatBlk ((b), ("" s ""), sizeof (s) - 1)
#define bTrunc(b,n) ((btrunc)((b), (n)))
#define bReplaceAll(b,find,repl,pos) ((bfindreplace)((b),(find),(repl),(pos)))
#define bUppercase(b) ((btoupper)(b))
#define bLowercase(b) ((btolower)(b))
#define bCaselessCmp(a,b) ((bstricmp)((a), (b)))
#define bCaselessNCmp(a,b,n) ((bstrnicmp)((a), (b), (n)))
#define bBase64Decode(b) (bBase64DecodeEx ((b), NULL))
#define bUuDecode(b) (bUuDecodeEx ((b), NULL))
/* Unusual functions */
extern struct bStream * bsFromBstr (const_bstring b);
extern bstring bTail (bstring b, int n);
extern bstring bHead (bstring b, int n);
extern int bSetCstrChar (bstring a, int pos, char c);
extern int bSetChar (bstring b, int pos, char c);
extern int bFill (bstring a, char c, int len);
extern int bReplicate (bstring b, int n);
extern int bReverse (bstring b);
extern int bInsertChrs (bstring b, int pos, int len, unsigned char c, unsigned char fill);
extern bstring bStrfTime (const char * fmt, const struct tm * timeptr);
#define bAscTime(t) (bStrfTime ("%c\n", (t)))
#define bCTime(t) ((t) ? bAscTime (localtime (t)) : NULL)
/* Spacing formatting */
extern int bJustifyLeft (bstring b, int space);
extern int bJustifyRight (bstring b, int width, int space);
extern int bJustifyMargin (bstring b, int width, int space);
extern int bJustifyCenter (bstring b, int width, int space);
/* Esoteric standards specific functions */
extern char * bStr2NetStr (const_bstring b);
extern bstring bNetStr2Bstr (const char * buf);
extern bstring bBase64Encode (const_bstring b);
extern bstring bBase64DecodeEx (const_bstring b, int * boolTruncError);
extern struct bStream * bsUuDecode (struct bStream * sInp, int * badlines);
extern bstring bUuDecodeEx (const_bstring src, int * badlines);
extern bstring bUuEncode (const_bstring src);
extern bstring bYEncode (const_bstring src);
extern bstring bYDecode (const_bstring src);
/* Writable stream */
typedef int (* bNwrite) (const void * buf, size_t elsize, size_t nelem, void * parm);
struct bwriteStream * bwsOpen (bNwrite writeFn, void * parm);
int bwsWriteBstr (struct bwriteStream * stream, const_bstring b);
int bwsWriteBlk (struct bwriteStream * stream, void * blk, int len);
int bwsWriteFlush (struct bwriteStream * stream);
int bwsIsEOF (const struct bwriteStream * stream);
int bwsBuffLength (struct bwriteStream * stream, int sz);
void * bwsClose (struct bwriteStream * stream);
/* Security functions */
#define bSecureDestroy(b) { \
bstring bstr__tmp = (b); \
if (bstr__tmp && bstr__tmp->mlen > 0 && bstr__tmp->data) { \
(void) memset (bstr__tmp->data, 0, (size_t) bstr__tmp->mlen); \
bdestroy (bstr__tmp); \
} \
}
#define bSecureWriteProtect(t) { \
if ((t).mlen >= 0) { \
if ((t).mlen > (t).slen)) { \
(void) memset ((t).data + (t).slen, 0, (size_t) (t).mlen - (t).slen); \
} \
(t).mlen = -1; \
} \
}
extern bstring bSecureInput (int maxlen, int termchar,
bNgetc vgetchar, void * vgcCtx);
#ifdef __cplusplus
}
#endif
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,305 @@
/*
* This source file is part of the bstring string library. This code was
* written by Paul Hsieh in 2002-2010, and is covered by either the 3-clause
* BSD open source license or GPL v2.0. Refer to the accompanying documentation
* for details on usage and license.
*/
// Modifications copyright Amazon.com, Inc. or its affiliates
/*
* bstrlib.h
*
* This file is the header file for the core module for implementing the
* bstring functions.
*/
#ifndef BSTRLIB_INCLUDE
#define BSTRLIB_INCLUDE
#ifdef __cplusplus
extern "C" {
#endif
#include <stdarg.h>
#include <string.h>
#include <limits.h>
#include <ctype.h>
#if !defined (BSTRLIB_VSNP_OK) && !defined (BSTRLIB_NOVSNP)
# if defined (__TURBOC__) && !defined (__BORLANDC__)
# define BSTRLIB_NOVSNP
# endif
#endif
#define BSTR_ERR (-1)
#define BSTR_OK (0)
#define BSTR_BS_BUFF_LENGTH_GET (0)
typedef struct tagbstring * bstring;
typedef const struct tagbstring * const_bstring;
/* Copy functions */
#define cstr2bstr bfromcstr
extern bstring bfromcstr (const char * str);
extern bstring bfromcstralloc (int mlen, const char * str);
extern bstring blk2bstr (const void * blk, int len);
extern char * bstr2cstr (const_bstring s, char z);
extern int bcstrfree (char * s);
extern bstring bstrcpy (const_bstring b1);
extern int bassign (bstring a, const_bstring b);
extern int bassignmidstr (bstring a, const_bstring b, int left, int len);
extern int bassigncstr (bstring a, const char * str);
extern int bassignblk (bstring a, const void * s, int len);
/* Destroy function */
extern int bdestroy (bstring b);
/* Space allocation hinting functions */
extern int balloc (bstring s, int len);
extern int ballocmin (bstring b, int len);
/* Substring extraction */
extern bstring bmidstr (const_bstring b, int left, int len);
/* Various standard manipulations */
extern int bconcat (bstring b0, const_bstring b1);
extern int bconchar (bstring b0, char c);
extern int bcatcstr (bstring b, const char * s);
extern int bcatblk (bstring b, const void * s, int len);
extern int binsert (bstring s1, int pos, const_bstring s2, unsigned char fill);
extern int binsertch (bstring s1, int pos, int len, unsigned char fill);
extern int breplace (bstring b1, int pos, int len, const_bstring b2, unsigned char fill);
extern int bdelete (bstring s1, int pos, int len);
extern int bsetstr (bstring b0, int pos, const_bstring b1, unsigned char fill);
extern int btrunc (bstring b, int n);
/* Scan/search functions */
extern int bstricmp (const_bstring b0, const_bstring b1);
extern int bstrnicmp (const_bstring b0, const_bstring b1, int n);
extern int biseqcaseless (const_bstring b0, const_bstring b1);
extern int bisstemeqcaselessblk (const_bstring b0, const void * blk, int len);
extern int biseq (const_bstring b0, const_bstring b1);
extern int bisstemeqblk (const_bstring b0, const void * blk, int len);
extern int biseqcstr (const_bstring b, const char * s);
extern int biseqcstrcaseless (const_bstring b, const char * s);
extern int bstrcmp (const_bstring b0, const_bstring b1);
extern int bstrncmp (const_bstring b0, const_bstring b1, int n);
extern int binstr (const_bstring s1, int pos, const_bstring s2);
extern int binstrr (const_bstring s1, int pos, const_bstring s2);
extern int binstrcaseless (const_bstring s1, int pos, const_bstring s2);
extern int binstrrcaseless (const_bstring s1, int pos, const_bstring s2);
extern int bstrchrp (const_bstring b, int c, int pos);
extern int bstrrchrp (const_bstring b, int c, int pos);
#define bstrchr(b,c) bstrchrp ((b), (c), 0)
#define bstrrchr(b,c) bstrrchrp ((b), (c), blength(b)-1)
extern int binchr (const_bstring b0, int pos, const_bstring b1);
extern int binchrr (const_bstring b0, int pos, const_bstring b1);
extern int bninchr (const_bstring b0, int pos, const_bstring b1);
extern int bninchrr (const_bstring b0, int pos, const_bstring b1);
extern int bfindreplace (bstring b, const_bstring find, const_bstring repl, int pos);
extern int bfindreplacecaseless (bstring b, const_bstring find, const_bstring repl, int pos);
/* List of string container functions */
struct bstrList {
int qty, mlen;
bstring * entry;
};
extern struct bstrList * bstrListCreate (void);
extern int bstrListDestroy (struct bstrList * sl);
extern int bstrListAlloc (struct bstrList * sl, int msz);
extern int bstrListAllocMin (struct bstrList * sl, int msz);
/* String split and join functions */
extern struct bstrList * bsplit (const_bstring str, unsigned char splitChar);
extern struct bstrList * bsplits (const_bstring str, const_bstring splitStr);
extern struct bstrList * bsplitstr (const_bstring str, const_bstring splitStr);
extern bstring bjoin (const struct bstrList * bl, const_bstring sep);
extern int bsplitcb (const_bstring str, unsigned char splitChar, int pos,
int (* cb) (void * parm, int ofs, int len), void * parm);
extern int bsplitscb (const_bstring str, const_bstring splitStr, int pos,
int (* cb) (void * parm, int ofs, int len), void * parm);
extern int bsplitstrcb (const_bstring str, const_bstring splitStr, int pos,
int (* cb) (void * parm, int ofs, int len), void * parm);
/* Miscellaneous functions */
extern int bpattern (bstring b, int len);
extern int btoupper (bstring b);
extern int btolower (bstring b);
extern int bltrimws (bstring b);
extern int brtrimws (bstring b);
extern int btrimws (bstring b);
/* <*>printf format functions */
#if !defined (BSTRLIB_NOVSNP)
extern bstring bformat (const char * fmt, ...);
extern int bformata (bstring b, const char * fmt, ...);
extern int bassignformat (bstring b, const char * fmt, ...);
extern int bvcformata (bstring b, int count, const char * fmt, va_list arglist);
#define bvformata(ret, b, fmt, lastarg) { \
bstring bstrtmp_b = (b); \
const char * bstrtmp_fmt = (fmt); \
int bstrtmp_r = BSTR_ERR, bstrtmp_sz = 16; \
for (;;) { \
va_list bstrtmp_arglist; \
va_start (bstrtmp_arglist, lastarg); \
bstrtmp_r = bvcformata (bstrtmp_b, bstrtmp_sz, bstrtmp_fmt, bstrtmp_arglist); \
va_end (bstrtmp_arglist); \
if (bstrtmp_r >= 0) { /* Everything went ok */ \
bstrtmp_r = BSTR_OK; \
break; \
} else if (-bstrtmp_r <= bstrtmp_sz) { /* A real error? */ \
bstrtmp_r = BSTR_ERR; \
break; \
} \
bstrtmp_sz = -bstrtmp_r; /* Doubled or target size */ \
} \
ret = bstrtmp_r; \
}
#endif
typedef int (*bNgetc) (void *parm);
typedef size_t (* bNread) (void *buff, size_t elsize, size_t nelem, void *parm);
/* Input functions */
extern bstring bgets (bNgetc getcPtr, void * parm, char terminator);
extern bstring bread (bNread readPtr, void * parm);
extern int bgetsa (bstring b, bNgetc getcPtr, void * parm, char terminator);
extern int bassigngets (bstring b, bNgetc getcPtr, void * parm, char terminator);
extern int breada (bstring b, bNread readPtr, void * parm);
/* Stream functions */
extern struct bStream * bsopen (bNread readPtr, void * parm);
extern void * bsclose (struct bStream * s);
extern int bsbufflength (struct bStream * s, int sz);
extern int bsreadln (bstring b, struct bStream * s, char terminator);
extern int bsreadlns (bstring r, struct bStream * s, const_bstring term);
extern int bsread (bstring b, struct bStream * s, int n);
extern int bsreadlna (bstring b, struct bStream * s, char terminator);
extern int bsreadlnsa (bstring r, struct bStream * s, const_bstring term);
extern int bsreada (bstring b, struct bStream * s, int n);
extern int bsunread (struct bStream * s, const_bstring b);
extern int bspeek (bstring r, const struct bStream * s);
extern int bssplitscb (struct bStream * s, const_bstring splitStr,
int (* cb) (void * parm, int ofs, const_bstring entry), void * parm);
extern int bssplitstrcb (struct bStream * s, const_bstring splitStr,
int (* cb) (void * parm, int ofs, const_bstring entry), void * parm);
extern int bseof (const struct bStream * s);
struct tagbstring {
int mlen;
int slen;
unsigned char * data;
};
/* Accessor macros */
#define blengthe(b, e) (((b) == (void *)0 || (b)->slen < 0) ? (int)(e) : ((b)->slen))
#define blength(b) (blengthe ((b), 0))
#define bdataofse(b, o, e) (((b) == (void *)0 || (b)->data == (void*)0) ? (char *)(e) : ((char *)(b)->data) + (o))
#define bdataofs(b, o) (bdataofse ((b), (o), (void *)0))
#define bdatae(b, e) (bdataofse (b, 0, e))
#define bdata(b) (bdataofs (b, 0))
#define bchare(b, p, e) ((((unsigned)(p)) < (unsigned)blength(b)) ? ((b)->data[(p)]) : (e))
#define bchar(b, p) bchare ((b), (p), '\0')
/* Static constant string initialization macro */
#define bsStaticMlen(q,m) {(m), (int) sizeof(q)-1, (unsigned char *) ("" q "")}
#if defined(_MSC_VER)
/* There are many versions of MSVC which emit __LINE__ as a non-constant. */
# define bsStatic(q) bsStaticMlen(q,-32)
#endif
#ifndef bsStatic
# define bsStatic(q) bsStaticMlen(q,-__LINE__)
#endif
/* Static constant block parameter pair */
#define bsStaticBlkParms(q) ((void *)("" q "")), ((int) sizeof(q)-1)
/* Reference building macros */
#define cstr2tbstr btfromcstr
#define btfromcstr(t,s) { \
(t).data = (unsigned char *) (s); \
(t).slen = ((t).data) ? ((int) (strlen) ((char *)(t).data)) : 0; \
(t).mlen = -1; \
}
#define blk2tbstr(t,s,l) { \
(t).data = (unsigned char *) (s); \
(t).slen = l; \
(t).mlen = -1; \
}
#define btfromblk(t,s,l) blk2tbstr(t,s,l)
#define bmid2tbstr(t,b,p,l) { \
const_bstring bstrtmp_s = (b); \
if (bstrtmp_s && bstrtmp_s->data && bstrtmp_s->slen >= 0) { \
int bstrtmp_left = (p); \
int bstrtmp_len = (l); \
if (bstrtmp_left < 0) { \
bstrtmp_len += bstrtmp_left; \
bstrtmp_left = 0; \
} \
if (bstrtmp_len > bstrtmp_s->slen - bstrtmp_left) \
bstrtmp_len = bstrtmp_s->slen - bstrtmp_left; \
if (bstrtmp_len <= 0) { \
(t).data = (unsigned char *)""; \
(t).slen = 0; \
} else { \
(t).data = bstrtmp_s->data + bstrtmp_left; \
(t).slen = bstrtmp_len; \
} \
} else { \
(t).data = (unsigned char *)""; \
(t).slen = 0; \
} \
(t).mlen = -__LINE__; \
}
#define btfromblkltrimws(t,s,l) { \
int bstrtmp_idx = 0, bstrtmp_len = (l); \
unsigned char * bstrtmp_s = (s); \
if (bstrtmp_s && bstrtmp_len >= 0) { \
for (; bstrtmp_idx < bstrtmp_len; bstrtmp_idx++) { \
if (!isspace (bstrtmp_s[bstrtmp_idx])) break; \
} \
} \
(t).data = bstrtmp_s + bstrtmp_idx; \
(t).slen = bstrtmp_len - bstrtmp_idx; \
(t).mlen = -__LINE__; \
}
#define btfromblkrtrimws(t,s,l) { \
int bstrtmp_len = (l) - 1; \
unsigned char * bstrtmp_s = (s); \
if (bstrtmp_s && bstrtmp_len >= 0) { \
for (; bstrtmp_len >= 0; bstrtmp_len--) { \
if (!isspace (bstrtmp_s[bstrtmp_len])) break; \
} \
} \
(t).data = bstrtmp_s; \
(t).slen = bstrtmp_len + 1; \
(t).mlen = -__LINE__; \
}
#define btfromblktrimws(t,s,l) { \
int bstrtmp_idx = 0, bstrtmp_len = (l) - 1; \
unsigned char * bstrtmp_s = (s); \
if (bstrtmp_s && bstrtmp_len >= 0) { \
for (; bstrtmp_idx <= bstrtmp_len; bstrtmp_idx++) { \
if (!isspace (bstrtmp_s[bstrtmp_idx])) break; \
} \
for (; bstrtmp_len >= bstrtmp_idx; bstrtmp_len--) { \
if (!isspace (bstrtmp_s[bstrtmp_len])) break; \
} \
} \
(t).data = bstrtmp_s + bstrtmp_idx; \
(t).slen = bstrtmp_len + 1 - bstrtmp_idx; \
(t).mlen = -__LINE__; \
}
/* Write protection macros */
#define bwriteprotect(t) { if ((t).mlen >= 0) (t).mlen = -1; }
#define bwriteallow(t) { if ((t).mlen == -1) (t).mlen = (t).slen + ((t).slen == 0); }
#define biswriteprotected(t) ((t).mlen <= 0)
#ifdef __cplusplus
}
#endif
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,29 @@
Copyright (c) 2002-2008 Paul Hsieh
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
Neither the name of bstrlib nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,172 @@
Better String library Porting Guide
-----------------------------------
by Paul Hsieh
The bstring library is an attempt to provide improved string processing
functionality to the C and C++ language. At the heart of the bstring library
is the management of "bstring"s which are a significant improvement over '\0'
terminated char buffers. See the accompanying documenation file bstrlib.txt
for more information.
===============================================================================
Identifying the Compiler
------------------------
Bstrlib has been tested on the following compilers:
Microsoft Visual C++
Watcom C/C++ (32 bit flat)
Intel's C/C++ compiler (on Windows)
The GNU C/C++ compiler (on Windows/Linux on x86 and PPC64)
Borland C++
Turbo C
There are slight differences in these compilers which requires slight
differences in the implementation of Bstrlib. These are accomodated in the
same sources using #ifdef/#if defined() on compiler specific macros. To
port Bstrlib to a new compiler not listed above, it is recommended that the
same strategy be followed. If you are unaware of the compiler specific
identifying preprocessor macro for your compiler you might find it here:
http://predef.sourceforge.net/precomp.html
Note that Intel C/C++ on Windows sets the Microsoft identifier: _MSC_VER.
16-bit vs. 32-bit vs. 64-bit Systems
------------------------------------
Bstrlib has been architected to deal with strings of length between 0 and
INT_MAX (inclusive). Since the values of int are never higher than size_t
there will be no issue here. Note that on most 64-bit systems int is 32-bit.
Dependency on The C-Library
---------------------------
Bstrlib uses the functions memcpy, memmove, malloc, realloc, free and
vsnprintf. Many free standing C compiler implementations that have a mode in
which the C library is not available will typically not include these
functions which will make porting Bstrlib to it onerous. Bstrlib is not
designed for such bare bones compiler environments. This usually includes
compilers that target ROM environments.
Porting Issues
--------------
Bstrlib has been written completely in ANSI/ISO C and ISO C++, however, there
are still a few porting issues. These are described below.
1. The vsnprintf () function.
Unfortunately, the earlier ANSI/ISO C standards did not include this function.
If the compiler of interest does not support this function then the
BSTRLIB_NOVSNP should be defined via something like:
#if !defined (BSTRLIB_VSNP_OK) && !defined (BSTRLIB_NOVSNP)
# if defined (__TURBOC__) || defined (__COMPILERVENDORSPECIFICMACRO__)
# define BSTRLIB_NOVSNP
# endif
#endif
which appears at the top of bstrlib.h. Note that the bformat(a) functions
will not be declared or implemented if the BSTRLIB_NOVSNP macro is set. If
the compiler has renamed vsnprintf() to some other named function, then
search for the definition of the exvsnprintf macro in bstrlib.c file and be
sure its defined appropriately:
#if defined (__COMPILERVENDORSPECIFICMACRO__)
# define exvsnprintf(r,b,n,f,a) {r=__compiler_specific_vsnprintf(b,n,f,a);}
#else
# define exvsnprintf(r,b,n,f,a) {r=vsnprintf(b,n,f,a);}
#endif
Take notice of the return value being captured in the variable r. It is
assumed that r exceeds n if and only if the underlying vsnprintf function has
determined what the true maximal output length would be for output if the
buffer were large enough to hold it. Non-modern implementations must output a
lesser number (the macro can and should be modified to ensure this).
2. Weak C++ compiler.
C++ is a much more complicated language to implement than C. This has lead
to varying quality of compiler implementations. The weaknesses isolated in
the initial ports are inclusion of the Standard Template Library,
std::iostream and exception handling. By default it is assumed that the C++
compiler supports all of these things correctly. If your compiler does not
support one or more of these define the corresponding macro:
BSTRLIB_CANNOT_USE_STL
BSTRLIB_CANNOT_USE_IOSTREAM
BSTRLIB_DOESNT_THROW_EXCEPTIONS
The compiler specific detected macro should be defined at the top of
bstrwrap.h in the Configuration defines section. Note that these disabling
macros can be overrided with the associated enabling macro if a subsequent
version of the compiler gains support. (For example, its possible to rig
up STLport to provide STL support for WATCOM C/C++, so -DBSTRLIB_CAN_USE_STL
can be passed in as a compiler option.)
3. The bsafe module, and reserved words.
The bsafe module is in gross violation of the ANSI/ISO C standard in the
sense that it redefines what could be implemented as reserved words on a
given compiler. The typical problem is that a compiler may inline some of the
functions and thus not be properly overridden by the definitions in the bsafe
module. It is also possible that a compiler may prohibit the redefinitions in
the bsafe module. Compiler specific action will be required to deal with
these situations.
Platform Specific Files
-----------------------
The makefiles for the examples are basically setup of for particular
environments for each platform. In general these makefiles are not portable
and should be constructed as necessary from scratch for each platform.
Testing a port
--------------
To test that a port compiles correctly do the following:
1. Build a sample project that includes the bstrlib, bstraux, bstrwrap, and
bsafe modules.
2. Compile bstest against the bstrlib module.
3. Run bstest and ensure that 0 errors are reported.
4. Compile test against the bstrlib and bstrwrap modules.
5. Run test and ensure that 0 errors are reported.
6. Compile each of the examples (except for the "re" example, which may be
complicated and is not a real test of bstrlib and except for the mfcbench
example which is Windows specific.)
7. Run each of the examples.
The builds must have 0 errors, and should have the absolute minimum number of
warnings (in most cases can be reduced to 0.) The result of execution should
be essentially identical on each platform.
Performance
-----------
Different CPU and compilers have different capabilities in terms of
performance. It is possible for Bstrlib to assume performance
characteristics that a platform doesn't have (since it was primarily
developed on just one platform). The goal of Bstrlib is to provide very good
performance on all platforms regardless of this but without resorting to
extreme measures (such as using assembly language, or non-portable intrinsics
or library extensions.)
There are two performance benchmarks that can be found in the example/
directory. They are: cbench.c and cppbench.cpp. These are variations and
expansions of a benchmark for another string library. They don't cover all
string functionality, but do include the most basic functions which will be
common in most string manipulation kernels.
...............................................................................
Feedback
--------
In all cases, you may email issues found to the primary author of Bstrlib at
the email address: websnarf@users.sourceforge.net
===============================================================================
@@ -0,0 +1,221 @@
Better String library Security Statement
----------------------------------------
by Paul Hsieh
===============================================================================
Introduction
------------
The Better String library (hereafter referred to as Bstrlib) is an attempt to
provide improved string processing functionality to the C and C++ languages.
At the heart of the Bstrlib is the management of "bstring"s which are a
significant improvement over '\0' terminated char buffers. See the
accompanying documenation file bstrlib.txt for more information.
DISCLAIMER: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Like any software, there is always a possibility of failure due to a flawed
implementation. Nevertheless a good faith effort has been made to minimize
such flaws in Bstrlib. Also, use of Bstrlib by itself will not make an
application secure or free from implementation failures. However, it is the
author's conviction that use of Bstrlib can greatly facilitate the creation
of software meeting the highest possible standards of security.
Part of the reason why this document has been created, is for the purpose of
security auditing, or the creation of further "Statements on Security" for
software that is created that uses Bstrlib. An auditor may check the claims
below against Bstrlib, and use this as a basis for analysis of software which
uses Bstrlib.
===============================================================================
Statement on Security
---------------------
This is a document intended to give consumers of the Better String Library
who are interested in security an idea of where the Better String Library
stands on various security issues. Any deviation observed in the actual
library itself from the descriptions below should be considered an
implementation error, not a design flaw.
This statement is not an analytical proof of correctness or an outline of one
but rather an assertion similar to a scientific claim or hypothesis. By use,
testing and open independent examination (otherwise known as scientific
falsifiability), the credibility of the claims made below can rise to the
level of an established theory.
Common security issues:
.......................
1. Buffer Overflows
The Bstrlib API allows the programmer a way to deal with strings without
having to deal with the buffers containing them. Ordinary usage of the
Bstrlib API itself makes buffer overflows impossible.
Furthermore, the Bstrlib API has a superset of basic string functionality as
compared to the C library's char * functions, C++'s std::string class and
Microsoft's MFC based CString class. It also has abstracted mechanisms for
dealing with IO. This is important as it gives developers a way of migrating
all their code from a functionality point of view.
2. Memory size overflow/wrap around attack
Bstrlib is, by design, impervious to memory size overflow attacks. The
reason is it is resiliant to length overflows is that bstring lengths are
bounded above by INT_MAX, instead of ~(size_t)0. So length addition
overflows cause a wrap around of the integer value making them negative
causing balloc() to fail before an erroneous operation can occurr. Attempted
conversions of char * strings which may have lengths greater than INT_MAX are
detected and the conversion is aborted.
It is unknown if this property holds on machines that don't represent
integers as 2s complement. It is recommended that Bstrlib be carefully
auditted by anyone using a system which is not 2s complement based.
3. Constant string protection
Bstrlib implements runtime enforced constant and read-only string semantics.
I.e., bstrings which are declared as constant via the bsStatic() macro cannot
be modified or deallocated directly through the Bstrlib API, and this cannot
be subverted by casting or other type coercion. This is independent of the
use of the const_bstring data type.
The Bstrlib C API uses the type const_bstring to specify bstring parameters
whose contents do not change. Although the C language cannot enforce this,
this is nevertheless guaranteed by the implementation of the Bstrlib library
of C functions. The C++ API enforces the const attribute on CBString types
correctly.
4. Aliased bstring support
Bstrlib detects and supports aliased parameter management throughout the API.
The kind of aliasing that is allowed is the one where pointers of the same
basic type may be pointing to overlapping objects (this is the assumption the
ANSI C99 specification makes.) Each function behaves as if all read-only
parameters were copied to temporaries which are used in their stead before
the function is enacted (it rarely actually does this). No function in the
Bstrlib uses the "restrict" parameter attribute from the ANSI C99
specification.
5. Information leaking
In bstraux.h, using the semantically equivalent macros bSecureDestroy() and
bSecureWriteProtect() in place of bdestroy() and bwriteprotect() respectively
will ensure that stale data does not linger in the heap's free space after
strings have been released back to memory. Created bstrings or CBStrings
are not linked to anything external to themselves, and thus cannot expose
deterministic data leaking. If a bstring is resized, the preimage may exist
as a copy that is released to the heap. Thus for sensitive data, the bstring
should be sufficiently presized before manipulated so that it is not resized.
bSecureInput() has been supplied in bstraux.c, which can be used to obtain
input securely without any risk of leaving any part of the input image in the
heap except for the allocated bstring that is returned.
6. Memory leaking
Bstrlib can be built using memdbg.h enabled via the BSTRLIB_MEMORY_DEBUG
macro. User generated definitions for malloc, realloc and free can then be
supplied which can implement special strategies for memory corruption
detection or memory leaking. Otherwise, bstrlib does not do anything out of
the ordinary to attempt to deal with the standard problem of memory leaking
(i.e., losing references to allocated memory) when programming in the C and
C++ languages. However, it does not compound the problem any more than exists
either, as it doesn't have any intrinsic inescapable leaks in it. Bstrlib
does not preclude the use of automatic garbage collection mechanisms such as
the Boehm garbage collector.
7. Encryption
Bstrlib does not present any built-in encryption mechanism. However, it
supports full binary contents in its data buffers, so any standard block
based encryption mechanism can make direct use of bstrings/CBStrings for
buffer management.
8. Double freeing
Freeing a pointer that is already free is an extremely rare, but nevertheless
a potentially ruthlessly corrupting operation (its possible to cause Win 98 to
reboot, by calling free mulitiple times on already freed data using the WATCOM
CRT.) Bstrlib invalidates the bstring header data before freeing, so that in
many cases a double free will be detected and an error will be reported
(though this behaviour is not guaranteed and should not be relied on).
Using bstrFree pervasively (instead of bdestroy) can lead to somewhat
improved invalid free avoidance (it is completely safe whenever bstring
instances are only stored in unique variables). For example:
struct tagbstring hw = bsStatic ("Hello, world");
bstring cpHw = bstrcpy (&hw);
#ifdef NOT_QUITE_AS_SAFE
bdestroy (cpHw); /* Never fail */
bdestroy (cpHw); /* Error sometimes detected at runtime */
bdestroy (&hw); /* Error detected at run time */
#else
bstrFree (cpHw); /* Never fail */
bstrFree (cpHw); /* Will do nothing */
bstrFree (&hw); /* Will lead to a compile time error */
#endif
9. Resource based denial of service
bSecureInput() has been supplied in bstraux.c. It has an optional upper limit
for input length. But unlike fgets(), it is also easily determined if the
buffer has been truncated early. In this way, a program can set an upper limit
on input sizes while still allowing for implementing context specific
truncation semantics (i.e., does the program consume but dump the extra
input, or does it consume it in later inputs?)
10. Mixing char *'s and bstrings
The bstring and char * representations are not identical. So there is a risk
when converting back and forth that data may lost. Essentially bstrings can
contain '\0' as a valid non-terminating character, while char * strings
cannot and in fact must use the character as a terminator. The risk of data
loss is very low, since:
A) the simple method of only using bstrings in a char * semantically
compatible way is both easy to achieve and pervasively supported.
B) obtaining '\0' content in a string is either deliberate or indicative
of another, likely more serious problem in the code.
C) the library comes with various functions which deal with this issue
(namely: bfromcstr(), bstr2cstr (), and bSetCstrChar ())
Marginal security issues:
.........................
11. 8-bit versus 9-bit portability
Bstrlib uses CHAR_BIT and other limits.h constants to the maximum extent
possible to avoid portability problems. However, Bstrlib has not been tested
on any system that does not represent char as 8-bits. So whether or not it
works on 9-bit systems is an open question. It is recommended that Bstrlib be
carefully auditted by anyone using a system in which CHAR_BIT is not 8.
12. EBCDIC/ASCII/UTF-8 data representation attacks.
Bstrlib uses ctype.h functions to ensure that it remains portable to non-
ASCII systems. It also checks range to make sure it is well defined even for
data that ANSI does not define for the ctype functions.
Obscure issues:
...............
13. Data attributes
There is no support for a Perl-like "taint" attribute, however, an example of
how to do this using C++'s type system is given as an example.
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,167 @@
// Modifications copyright Amazon.com, Inc. or its affiliates
#include "internal_includes/hlslccToolkit.h"
#include "internal_includes/debug.h"
#include "internal_includes/languages.h"
bool DoAssignmentDataTypesMatch(SHADER_VARIABLE_TYPE dest, SHADER_VARIABLE_TYPE src)
{
if (src == dest)
return true;
if ((dest == SVT_FLOAT || dest == SVT_FLOAT10 || dest == SVT_FLOAT16) &&
(src == SVT_FLOAT || src == SVT_FLOAT10 || src == SVT_FLOAT16))
return true;
if ((dest == SVT_INT || dest == SVT_INT12 || dest == SVT_INT16) &&
(src == SVT_INT || src == SVT_INT12 || src == SVT_INT16))
return true;
if ((dest == SVT_UINT || dest == SVT_UINT16) &&
(src == SVT_UINT || src == SVT_UINT16))
return true;
return false;
}
const char * GetConstructorForTypeGLSL(HLSLCrossCompilerContext* psContext, const SHADER_VARIABLE_TYPE eType, const int components, bool useGLSLPrecision)
{
const bool usePrecision = useGLSLPrecision && HavePrecisionQualifers(psContext->psShader->eTargetLanguage);
static const char * const uintTypes[] = { " ", "uint", "uvec2", "uvec3", "uvec4" };
static const char * const uint16Types[] = { " ", "mediump uint", "mediump uvec2", "mediump uvec3", "mediump uvec4" };
static const char * const intTypes[] = { " ", "int", "ivec2", "ivec3", "ivec4" };
static const char * const int16Types[] = { " ", "mediump int", "mediump ivec2", "mediump ivec3", "mediump ivec4" };
static const char * const int12Types[] = { " ", "lowp int", "lowp ivec2", "lowp ivec3", "lowp ivec4" };
static const char * const floatTypes[] = { " ", "float", "vec2", "vec3", "vec4" };
static const char * const float16Types[] = { " ", "mediump float", "mediump vec2", "mediump vec3", "mediump vec4" };
static const char * const float10Types[] = { " ", "lowp float", "lowp vec2", "lowp vec3", "lowp vec4" };
static const char * const boolTypes[] = { " ", "bool", "bvec2", "bvec3", "bvec4" };
ASSERT(components >= 1 && components <= 4);
switch (eType)
{
case SVT_UINT:
return uintTypes[components];
case SVT_UINT16:
return usePrecision ? uint16Types[components] : uintTypes[components];
case SVT_INT:
return intTypes[components];
case SVT_INT16:
return usePrecision ? int16Types[components] : intTypes[components];
case SVT_INT12:
return usePrecision ? int12Types[components] : intTypes[components];
case SVT_FLOAT:
return floatTypes[components];
case SVT_FLOAT16:
return usePrecision ? float16Types[components] : floatTypes[components];
case SVT_FLOAT10:
return usePrecision ? float10Types[components] : floatTypes[components];
case SVT_BOOL:
return boolTypes[components];
default:
ASSERT(0);
return "";
}
}
SHADER_VARIABLE_TYPE TypeFlagsToSVTType(const uint32_t typeflags)
{
if (typeflags & TO_FLAG_INTEGER)
return SVT_INT;
if (typeflags & TO_FLAG_UNSIGNED_INTEGER)
return SVT_UINT;
return SVT_FLOAT;
}
uint32_t SVTTypeToFlag(const SHADER_VARIABLE_TYPE eType)
{
if (eType == SVT_FLOAT16 || eType == SVT_FLOAT10 || eType == SVT_FLOAT)
{
return TO_FLAG_FLOAT;
}
if (eType == SVT_UINT || eType == SVT_UINT16)
{
return TO_FLAG_UNSIGNED_INTEGER;
}
else if (eType == SVT_INT || eType == SVT_INT16 || eType == SVT_INT12)
{
return TO_FLAG_INTEGER;
}
else
{
return TO_FLAG_NONE;
}
}
bool CanDoDirectCast(SHADER_VARIABLE_TYPE src, SHADER_VARIABLE_TYPE dest)
{
// uint<->int<->bool conversions possible
if ((src == SVT_INT || src == SVT_UINT || src == SVT_BOOL || src == SVT_INT12 || src == SVT_INT16 || src == SVT_UINT16) &&
(dest == SVT_INT || dest == SVT_UINT || dest == SVT_BOOL || dest == SVT_INT12 || dest == SVT_INT16 || dest == SVT_UINT16))
return true;
// float<->double possible
if ((src == SVT_FLOAT || src == SVT_DOUBLE || src == SVT_FLOAT16 || src == SVT_FLOAT10) &&
(dest == SVT_FLOAT || dest == SVT_DOUBLE || dest == SVT_FLOAT16 || dest == SVT_FLOAT10))
return true;
return false;
}
const char* GetBitcastOp(SHADER_VARIABLE_TYPE from, SHADER_VARIABLE_TYPE to)
{
static const char* intToFloat = "intBitsToFloat";
static const char* uintToFloat = "uintBitsToFloat";
static const char* floatToInt = "floatBitsToInt";
static const char* floatToUint = "floatBitsToUint";
if ((to == SVT_FLOAT || to == SVT_FLOAT16 || to == SVT_FLOAT10) && from == SVT_INT)
return intToFloat;
else if ((to == SVT_FLOAT || to == SVT_FLOAT16 || to == SVT_FLOAT10) && from == SVT_UINT)
return uintToFloat;
else if (to == SVT_INT && (from == SVT_FLOAT || from == SVT_FLOAT16 || from == SVT_FLOAT10))
return floatToInt;
else if (to == SVT_UINT && (from == SVT_FLOAT || from == SVT_FLOAT16 || from == SVT_FLOAT10))
return floatToUint;
ASSERT(0);
return "";
}
bool IsGmemReservedSlot(FRAMEBUFFER_FETCH_TYPE typeMask, const uint32_t regNumber)
{
if (((typeMask & FBF_ARM_COLOR) && regNumber == GMEM_ARM_COLOR_SLOT) ||
((typeMask & FBF_ARM_DEPTH) && regNumber == GMEM_ARM_DEPTH_SLOT) ||
((typeMask & FBF_ARM_STENCIL) && regNumber == GMEM_ARM_STENCIL_SLOT) ||
((typeMask & FBF_EXT_COLOR) && regNumber >= GMEM_FLOAT_START_SLOT))
{
return true;
}
return false;
}
const char * GetAuxArgumentName(const SHADER_VARIABLE_TYPE varType)
{
switch (varType)
{
case SVT_UINT:
case SVT_UINT8:
case SVT_UINT16:
return "uArg";
case SVT_INT:
case SVT_INT16:
case SVT_INT12:
return "iArg";
case SVT_FLOAT:
case SVT_FLOAT16:
case SVT_FLOAT10:
return "fArg";
case SVT_BOOL:
return "bArg";
default:
ASSERT(0);
return "";
}
}
@@ -0,0 +1,21 @@
// Modifications copyright Amazon.com, Inc. or its affiliates
// Modifications copyright Crytek GmbH
#ifndef DEBUG_H_
#define DEBUG_H_
#ifdef _DEBUG
#include "assert.h"
#define ASSERT(expr) CustomAssert(expr)
static void CustomAssert(int expression)
{
if(!expression)
{
assert(0);
}
}
#else
#define ASSERT(expr)
#endif
#endif
@@ -0,0 +1,21 @@
// Modifications copyright Amazon.com, Inc. or its affiliates
// Modifications copyright Crytek GmbH
#ifndef DECODE_H
#define DECODE_H
#include "internal_includes/structs.h"
Shader* DecodeDXBC(uint32_t* data);
//You don't need to call this directly because DecodeDXBC
//will call DecodeDX9BC if the shader looks
//like it is SM1/2/3.
Shader* DecodeDX9BC(const uint32_t* pui32Tokens);
void UpdateDeclarationReferences(Shader* psShader, Declaration* psDeclaration);
void UpdateInstructionReferences(Shader* psShader, Instruction* psInstruction);
#define FOURCC(a, b, c, d) ((uint32_t)(uint8_t)(a) | ((uint32_t)(uint8_t)(b) << 8) | ((uint32_t)(uint8_t)(c) << 16) | ((uint32_t)(uint8_t)(d) << 24))
#endif
@@ -0,0 +1,35 @@
// Modifications copyright Amazon.com, Inc. or its affiliates
#ifndef HLSLCC_TOOLKIT_DECLARATION_H
#define HLSLCC_TOOLKIT_DECLARATION_H
#include "hlslcc.h"
#include "bstrlib.h"
#include "internal_includes/structs.h"
#include <stdbool.h>
// Check if "src" type can be assigned directly to the "dest" type.
bool DoAssignmentDataTypesMatch(SHADER_VARIABLE_TYPE dest, SHADER_VARIABLE_TYPE src);
// Returns the constructor needed depending on the type, the number of components and the use of precision qualifier.
const char * GetConstructorForTypeGLSL(HLSLCrossCompilerContext* psContext, const SHADER_VARIABLE_TYPE eType, const int components, bool useGLSLPrecision);
// Transform from a variable type to a shader variable flag.
uint32_t SVTTypeToFlag(const SHADER_VARIABLE_TYPE eType);
// Transform from a shader variable flag to a shader variable type.
SHADER_VARIABLE_TYPE TypeFlagsToSVTType(const uint32_t typeflags);
// Check if the "src" type can be casted using a constructor to the "dest" type (without bitcasting).
bool CanDoDirectCast(SHADER_VARIABLE_TYPE src, SHADER_VARIABLE_TYPE dest);
// Returns the bitcast operation needed to assign the "src" type to the "dest" type
const char* GetBitcastOp(SHADER_VARIABLE_TYPE src, SHADER_VARIABLE_TYPE dest);
// Check if the register number is part of the ones we used for signaling GMEM input
bool IsGmemReservedSlot(FRAMEBUFFER_FETCH_TYPE type, const uint32_t regNumber);
// Return the name of an auxiliary variable used to save intermediate values to bypass driver issues
const char * GetAuxArgumentName(const SHADER_VARIABLE_TYPE varType);
#endif
@@ -0,0 +1,16 @@
// Modifications copyright Amazon.com, Inc. or its affiliates
// Modifications copyright Crytek GmbH
#ifdef _WIN32
#include <malloc.h>
#else
#include <stdlib.h>
#endif
#include <AzCore/PlatformDef.h>
AZ_PUSH_DISABLE_WARNING(4232, "-Wunknown-warning-option") // address of malloc/free/calloc/realloc are not static
void* (*hlslcc_malloc)(size_t size) = malloc;
void* (*hlslcc_calloc)(size_t num,size_t size) = calloc;
void (*hlslcc_free)(void *p) = free;
void* (*hlslcc_realloc)(void *p,size_t size) = realloc;
AZ_POP_DISABLE_WARNING
@@ -0,0 +1,15 @@
// Modifications copyright Amazon.com, Inc. or its affiliates
// Modifications copyright Crytek GmbH
#ifndef __HLSCC_MALLOC_H
#define __HLSCC_MALLOC_H
extern void* (*hlslcc_malloc)(size_t size);
extern void* (* hlslcc_calloc)(size_t num, size_t size);
extern void (* hlslcc_free)(void* p);
extern void* (* hlslcc_realloc)(void* p, size_t size);
#define bstr__alloc hlslcc_malloc
#define bstr__free hlslcc_free
#define bstr__realloc hlslcc_realloc
#endif
@@ -0,0 +1,242 @@
// Modifications copyright Amazon.com, Inc. or its affiliates
// Modifications copyright Crytek GmbH
#ifndef LANGUAGES_H
#define LANGUAGES_H
#include "hlslcc.h"
static int InOutSupported(const GLLang eLang)
{
if(eLang == LANG_ES_100 || eLang == LANG_120)
{
return 0;
}
return 1;
}
static int WriteToFragData(const GLLang eLang)
{
if(eLang == LANG_ES_100 || eLang == LANG_120)
{
return 1;
}
return 0;
}
static int ShaderBitEncodingSupported(const GLLang eLang)
{
if( eLang != LANG_ES_300 &&
eLang != LANG_ES_310 &&
eLang < LANG_330)
{
return 0;
}
return 1;
}
static int HaveOverloadedTextureFuncs(const GLLang eLang)
{
if(eLang == LANG_ES_100 || eLang == LANG_120)
{
return 0;
}
return 1;
}
//Only enable for ES.
//Not present in 120, ignored in other desktop languages.
static int HavePrecisionQualifers(const GLLang eLang)
{
if(eLang >= LANG_ES_100 && eLang <= LANG_ES_310)
{
return 1;
}
return 0;
}
//Only on vertex inputs and pixel outputs.
static int HaveLimitedInOutLocationQualifier(const GLLang eLang)
{
if(eLang >= LANG_330 || eLang == LANG_ES_300 || eLang == LANG_ES_310)
{
return 1;
}
return 0;
}
static int HaveInOutLocationQualifier(const GLLang eLang,const struct GlExtensions *extensions)
{
if(eLang >= LANG_410 || eLang == LANG_ES_310 || (extensions && ((GlExtensions*)extensions)->ARB_explicit_attrib_location))
{
return 1;
}
return 0;
}
//layout(binding = X) uniform {uniformA; uniformB;}
//layout(location = X) uniform uniform_name;
static int HaveUniformBindingsAndLocations(const GLLang eLang,const struct GlExtensions *extensions)
{
if(eLang >= LANG_430 || eLang == LANG_ES_310 || (extensions && ((GlExtensions*)extensions)->ARB_explicit_uniform_location))
{
return 1;
}
return 0;
}
static int DualSourceBlendSupported(const GLLang eLang)
{
if(eLang >= LANG_330)
{
return 1;
}
return 0;
}
static int SubroutinesSupported(const GLLang eLang)
{
if(eLang >= LANG_400)
{
return 1;
}
return 0;
}
//Before 430, flat/smooth/centroid/noperspective must match
//between fragment and its previous stage.
//HLSL bytecode only tells us the interpolation in pixel shader.
static int PixelInterpDependency(const GLLang eLang)
{
if(eLang < LANG_430)
{
return 1;
}
return 0;
}
static int HaveUVec(const GLLang eLang)
{
switch(eLang)
{
case LANG_ES_100:
case LANG_120:
return 0;
default:
break;
}
return 1;
}
static int HaveGather(const GLLang eLang)
{
if(eLang >= LANG_400 || eLang == LANG_ES_310)
{
return 1;
}
return 0;
}
static int HaveGatherNonConstOffset(const GLLang eLang)
{
if(eLang >= LANG_420 || eLang == LANG_ES_310)
{
return 1;
}
return 0;
}
static int HaveQueryLod(const GLLang eLang)
{
if(eLang >= LANG_400)
{
return 1;
}
return 0;
}
static int HaveQueryLevels(const GLLang eLang)
{
if(eLang >= LANG_430)
{
return 1;
}
return 0;
}
static int HaveAtomicCounter(const GLLang eLang)
{
if(eLang >= LANG_420 || eLang == LANG_ES_310)
{
return 1;
}
return 0;
}
static int HaveAtomicMem(const GLLang eLang)
{
if(eLang >= LANG_430)
{
return 1;
}
return 0;
}
static int HaveCompute(const GLLang eLang)
{
if(eLang >= LANG_430 || eLang == LANG_ES_310)
{
return 1;
}
return 0;
}
static int HaveImageLoadStore(const GLLang eLang)
{
if(eLang >= LANG_420 || eLang == LANG_ES_310)
{
return 1;
}
return 0;
}
static int EmulateDepthClamp(const GLLang eLang)
{
if (eLang >= LANG_ES_300 && eLang < LANG_120) //Requires gl_FragDepth available in fragment shader
{
return 1;
}
return 0;
}
static int HaveNoperspectiveInterpolation(const GLLang eLang)
{
if (eLang >= LANG_330)
{
return 1;
}
return 0;
}
static int EarlyDepthTestSupported(const GLLang eLang)
{
if ((eLang > LANG_410) || (eLang == LANG_ES_310))
{
return 1;
}
return 0;
}
static int StorageBlockBindingSupported(const GLLang eLang)
{
if (eLang >= LANG_430)
{
return 1;
}
return 0;
}
#endif
@@ -0,0 +1,42 @@
// Modifications copyright Amazon.com, Inc. or its affiliates
// Modifications copyright Crytek GmbH
#ifndef REFLECT_H
#define REFLECT_H
#include "hlslcc.h"
ResourceGroup ResourceTypeToResourceGroup(ResourceType);
int GetResourceFromBindingPoint(const ResourceGroup eGroup, const uint32_t ui32BindPoint, const ShaderInfo* psShaderInfo, ResourceBinding** ppsOutBinding);
void GetConstantBufferFromBindingPoint(const ResourceGroup eGroup, const uint32_t ui32BindPoint, const ShaderInfo* psShaderInfo, ConstantBuffer** ppsConstBuf);
int GetInterfaceVarFromOffset(uint32_t ui32Offset, ShaderInfo* psShaderInfo, ShaderVar** ppsShaderVar);
int GetInputSignatureFromRegister(const uint32_t ui32Register, const ShaderInfo* psShaderInfo, InOutSignature** ppsOut);
int GetOutputSignatureFromRegister(const uint32_t ui32Register, const uint32_t ui32Stream, const uint32_t ui32CompMask, ShaderInfo* psShaderInfo, InOutSignature** ppsOut);
int GetOutputSignatureFromSystemValue(SPECIAL_NAME eSystemValueType, uint32_t ui32SemanticIndex, ShaderInfo* psShaderInfo, InOutSignature** ppsOut);
int GetShaderVarFromOffset(const uint32_t ui32Vec4Offset, const uint32_t* pui32Swizzle, ConstantBuffer* psCBuf, ShaderVarType** ppsShaderVar, int32_t* pi32Index, int32_t* pi32Rebase);
typedef struct
{
uint32_t* pui32Inputs;
uint32_t* pui32Outputs;
uint32_t* pui32Resources;
uint32_t* pui32Interfaces;
uint32_t* pui32Inputs11;
uint32_t* pui32Outputs11;
uint32_t* pui32OutputsWithStreams;
} ReflectionChunks;
void LoadShaderInfo(const uint32_t ui32MajorVersion, const uint32_t ui32MinorVersion, const ReflectionChunks* psChunks, ShaderInfo* psInfo);
void LoadD3D9ConstantTable(const char* data, ShaderInfo* psInfo);
void FreeShaderInfo(ShaderInfo* psShaderInfo);
#endif
@@ -0,0 +1,36 @@
// Modifications copyright Amazon.com, Inc. or its affiliates
// Modifications copyright Crytek GmbH
#ifndef HLSLCC_SHADER_LIMITS_H
#define HLSLCC_SHADER_LIMITS_H
static enum
{
MAX_SHADER_VEC4_OUTPUT = 512
};
static enum
{
MAX_SHADER_VEC4_INPUT = 512
};
static enum
{
MAX_TEXTURES = 128
};
static enum
{
MAX_FORK_PHASES = 2
};
static enum
{
MAX_FUNCTION_BODIES = 1024
};
static enum
{
MAX_CLASS_TYPES = 1024
};
static enum
{
MAX_FUNCTION_POINTERS = 128
};
#endif
@@ -0,0 +1,374 @@
// Modifications copyright Amazon.com, Inc. or its affiliates
// Modifications copyright Crytek GmbH
#ifndef STRUCTS_H
#define STRUCTS_H
#include "hlslcc.h"
#include "bstrlib.h"
#include "internal_includes/tokens.h"
#include "internal_includes/reflect.h"
enum
{
MAX_SUB_OPERANDS = 3
};
typedef struct Operand_TAG
{
int iExtended;
OPERAND_TYPE eType;
OPERAND_MODIFIER eModifier;
OPERAND_MIN_PRECISION eMinPrecision;
int iIndexDims;
int indexRepresentation[4];
int writeMask;
int iGSInput;
int iWriteMaskEnabled;
int iNumComponents;
OPERAND_4_COMPONENT_SELECTION_MODE eSelMode;
uint32_t ui32CompMask;
uint32_t ui32Swizzle;
uint32_t aui32Swizzle[4];
uint32_t aui32ArraySizes[3];
uint32_t ui32RegisterNumber;
//If eType is OPERAND_TYPE_IMMEDIATE32
float afImmediates[4];
//If eType is OPERAND_TYPE_IMMEDIATE64
double adImmediates[4];
int iIntegerImmediate;
SPECIAL_NAME eSpecialName;
char pszSpecialName[64];
OPERAND_INDEX_REPRESENTATION eIndexRep[3];
struct Operand_TAG* psSubOperand[MAX_SUB_OPERANDS];
//One type for each component.
SHADER_VARIABLE_TYPE aeDataType[4];
#ifdef _DEBUG
uint64_t id;
#endif
} Operand;
typedef struct Instruction_TAG
{
OPCODE_TYPE eOpcode;
INSTRUCTION_TEST_BOOLEAN eBooleanTestType;
COMPARISON_DX9 eDX9TestType;
uint32_t ui32SyncFlags;
uint32_t ui32NumOperands;
uint32_t ui32FirstSrc;
Operand asOperands[6];
uint32_t bSaturate;
uint32_t ui32FuncIndexWithinInterface;
RESINFO_RETURN_TYPE eResInfoReturnType;
int bAddressOffset;
int iUAddrOffset;
int iVAddrOffset;
int iWAddrOffset;
RESOURCE_RETURN_TYPE xType, yType, zType, wType;
RESOURCE_DIMENSION eResDim;
#ifdef _DEBUG
uint64_t id;
#endif
} Instruction;
enum
{
MAX_IMMEDIATE_CONST_BUFFER_VEC4_SIZE = 1024
};
typedef struct ICBVec4_TAG
{
uint32_t a;
uint32_t b;
uint32_t c;
uint32_t d;
} ICBVec4;
typedef struct Declaration_TAG
{
OPCODE_TYPE eOpcode;
uint32_t ui32NumOperands;
Operand asOperands[2];
ICBVec4 asImmediateConstBuffer[MAX_IMMEDIATE_CONST_BUFFER_VEC4_SIZE];
//The declaration can set one of these
//values depending on the opcode.
union
{
uint32_t ui32GlobalFlags;
uint32_t ui32NumTemps;
RESOURCE_DIMENSION eResourceDimension;
CONSTANT_BUFFER_ACCESS_PATTERN eCBAccessPattern;
INTERPOLATION_MODE eInterpolation;
PRIMITIVE_TOPOLOGY eOutputPrimitiveTopology;
PRIMITIVE eInputPrimitive;
uint32_t ui32MaxOutputVertexCount;
TESSELLATOR_DOMAIN eTessDomain;
TESSELLATOR_PARTITIONING eTessPartitioning;
TESSELLATOR_OUTPUT_PRIMITIVE eTessOutPrim;
uint32_t aui32WorkGroupSize[3];
//Fork phase index followed by the instance count.
uint32_t aui32HullPhaseInstanceInfo[2];
float fMaxTessFactor;
uint32_t ui32IndexRange;
uint32_t ui32GSInstanceCount;
struct Interface_TAG
{
uint32_t ui32InterfaceID;
uint32_t ui32NumFuncTables;
uint32_t ui32ArraySize;
} interface;
} value;
struct UAV_TAG
{
uint32_t ui32GloballyCoherentAccess;
uint32_t ui32BufferSize;
uint8_t bCounter;
RESOURCE_RETURN_TYPE Type;
} sUAV;
struct TGSM_TAG
{
uint32_t ui32Stride;
uint32_t ui32Count;
} sTGSM;
struct IndexableTemp_TAG
{
uint32_t ui32RegIndex;
uint32_t ui32RegCount;
uint32_t ui32RegComponentSize;
} sIdxTemp;
uint32_t ui32TableLength;
uint32_t ui32TexReturnType;
} Declaration;
enum
{
MAX_TEMP_VEC4 = 512
};
enum
{
MAX_GROUPSHARED = 8
};
enum
{
MAX_DX9_IMMCONST = 256
};
typedef struct Shader_TAG
{
uint32_t ui32MajorVersion;
uint32_t ui32MinorVersion;
SHADER_TYPE eShaderType;
GLLang eTargetLanguage;
const struct GlExtensions *extensions;
int fp64;
//DWORDs in program code, including version and length tokens.
uint32_t ui32ShaderLength;
uint32_t ui32DeclCount;
Declaration* psDecl;
//Instruction* functions;//non-main subroutines
uint32_t aui32FuncTableToFuncPointer[MAX_FUNCTION_TABLES];//FIXME dynamic alloc
uint32_t aui32FuncBodyToFuncTable[MAX_FUNCTION_BODIES];
struct
{
uint32_t aui32FuncBodies[MAX_FUNCTION_BODIES];
}funcTable[MAX_FUNCTION_TABLES];
struct
{
uint32_t aui32FuncTables[MAX_FUNCTION_TABLES];
uint32_t ui32NumBodiesPerTable;
}funcPointer[MAX_FUNCTION_POINTERS];
uint32_t ui32NextClassFuncName[MAX_CLASS_TYPES];
uint32_t ui32InstCount;
Instruction* psInst;
const uint32_t* pui32FirstToken;//Reference for calculating current position in token stream.
//Hull shader declarations and instructions.
//psDecl, psInst are null for hull shaders.
uint32_t ui32HSDeclCount;
Declaration* psHSDecl;
uint32_t ui32HSControlPointDeclCount;
Declaration* psHSControlPointPhaseDecl;
uint32_t ui32HSControlPointInstrCount;
Instruction* psHSControlPointPhaseInstr;
uint32_t ui32ForkPhaseCount;
uint32_t aui32HSForkDeclCount[MAX_FORK_PHASES];
Declaration* apsHSForkPhaseDecl[MAX_FORK_PHASES];
uint32_t aui32HSForkInstrCount[MAX_FORK_PHASES];
Instruction* apsHSForkPhaseInstr[MAX_FORK_PHASES];
uint32_t ui32HSJoinDeclCount;
Declaration* psHSJoinPhaseDecl;
uint32_t ui32HSJoinInstrCount;
Instruction* psHSJoinPhaseInstr;
ShaderInfo sInfo;
int abScalarInput[MAX_SHADER_VEC4_INPUT];
int aIndexedOutput[MAX_SHADER_VEC4_OUTPUT];
int aIndexedInput[MAX_SHADER_VEC4_INPUT];
int aIndexedInputParents[MAX_SHADER_VEC4_INPUT];
RESOURCE_DIMENSION aeResourceDims[MAX_TEXTURES];
int aiInputDeclaredSize[MAX_SHADER_VEC4_INPUT];
int aiOutputDeclared[MAX_SHADER_VEC4_OUTPUT];
//Does not track built-in inputs.
int abInputReferencedByInstruction[MAX_SHADER_VEC4_INPUT];
int aiOpcodeUsed[NUM_OPCODES];
uint32_t ui32CurrentVertexOutputStream;
uint32_t ui32NumDx9ImmConst;
uint32_t aui32Dx9ImmConstArrayRemap[MAX_DX9_IMMCONST];
ShaderVarType sGroupSharedVarType[MAX_GROUPSHARED];
SHADER_VARIABLE_TYPE aeCommonTempVecType[MAX_TEMP_VEC4];
uint32_t bUseTempCopy;
FRAMEBUFFER_FETCH_TYPE eGmemType;
} Shader;
/* CONFETTI NOTE: DAVID SROUR
* The following is super sketchy, but at the moment,
* there is no way to figure out the type of a resource
* since HLSL has only register sets for the following:
* bool, int4, float4, sampler.
* THIS CODE IS DUPLICATED FROM HLSLcc METAL.
* IF ANYTHING CHANGES, BOTH TRANSLATORS SHOULD HAVE THE CHANGE.
* TODO: CONSOLIDATE THE 2 HLSLcc PROJECTS.
*/
enum
{
GMEM_FLOAT4_START_SLOT = 120
};
enum
{
GMEM_FLOAT3_START_SLOT = 112
};
enum
{
GMEM_FLOAT2_START_SLOT = 104
};
enum
{
GMEM_FLOAT_START_SLOT = 96
};
enum
{
GMEM_ARM_COLOR_SLOT = 93,
GMEM_ARM_DEPTH_SLOT = 94,
GMEM_ARM_STENCIL_SLOT = 95
};
/* CONFETTI NOTE: DAVID SROUR
* Following is the reserved slot for PLS extension (https://www.khronos.org/registry/gles/extensions/EXT/EXT_shader_pixel_local_storage.txt).
* It will get picked up when a RWStructuredBuffer resource is defined at the following reserved slot.
* Note that only one PLS struct can be present at a time otherwise the behavior is undefined.
*
* Types in the struct and their output conversion (each output variable will always be 4 bytes):
* float2 -> rg16f
* float3 -> r11f_g11f_b10f
* float4 -> rgba8
* uint -> r32ui
* int2 -> rg16i
* int4 -> rgba8i
*/
enum
{
GMEM_PLS_RO_SLOT = 60
}; // READ-ONLY
enum
{
GMEM_PLS_WO_SLOT = 61
}; // WRITE-ONLY
enum
{
GMEM_PLS_RW_SLOT = 62
}; // READ/WRITE
static const uint32_t MAIN_PHASE = 0;
static const uint32_t HS_FORK_PHASE = 1;
static const uint32_t HS_CTRL_POINT_PHASE = 2;
static const uint32_t HS_JOIN_PHASE = 3;
enum
{
NUM_PHASES = 4
};
enum
{
MAX_COLOR_MRT = 8
};
enum
{
INPUT_RENDERTARGET = 1 << 0,
OUTPUT_RENDERTARGET = 1 << 1
};
typedef struct HLSLCrossCompilerContext_TAG
{
bstring glsl;
bstring earlyMain;//Code to be inserted at the start of main()
bstring postShaderCode[NUM_PHASES];//End of main or before emit()
bstring debugHeader;
bstring* currentGLSLString;//either glsl or earlyMain
int havePostShaderCode[NUM_PHASES];
uint32_t currentPhase;
uint32_t rendertargetUse[MAX_COLOR_MRT];
int indent;
unsigned int flags;
Shader* psShader;
} HLSLCrossCompilerContext;
#endif
@@ -0,0 +1,19 @@
// Modifications copyright Amazon.com, Inc. or its affiliates
// Modifications copyright Crytek GmbH
#ifndef TO_GLSL_DECLARATION_H
#define TO_GLSL_DECLARATION_H
#include "internal_includes/structs.h"
void TranslateDeclaration(HLSLCrossCompilerContext* psContext, const Declaration* psDecl);
char* GetDeclaredInputName(const HLSLCrossCompilerContext* psContext, const SHADER_TYPE eShaderType, const Operand* psOperand);
char* GetDeclaredOutputName(const HLSLCrossCompilerContext* psContext, const SHADER_TYPE eShaderType, const Operand* psOperand, int* stream);
//Hull shaders have multiple phases.
//Each phase has its own temps.
//Convert to global temps for GLSL.
void ConsolidateHullTempVars(Shader* psShader);
#endif
@@ -0,0 +1,18 @@
// Modifications copyright Amazon.com, Inc. or its affiliates
// Modifications copyright Crytek GmbH
#ifndef TO_GLSL_INSTRUCTION_H
#define TO_GLSL_INSTRUCTION_H
#include "internal_includes/structs.h"
void TranslateInstruction(HLSLCrossCompilerContext* psContext, Instruction* psInst);
//For each MOV temp, immediate; check to see if the next instruction
//using that temp has an integer opcode. If so then the immediate value
//is flaged as having an integer encoding.
void MarkIntegerImmediates(HLSLCrossCompilerContext* psContext);
void SetDataTypes(HLSLCrossCompilerContext* psContext, Instruction* psInst, const int32_t i32InstCount, SHADER_VARIABLE_TYPE* aeCommonTempVecType);
#endif
@@ -0,0 +1,46 @@
// Modifications copyright Amazon.com, Inc. or its affiliates
// Modifications copyright Crytek GmbH
#ifndef TO_GLSL_OPERAND_H
#define TO_GLSL_OPERAND_H
#include "internal_includes/structs.h"
void TranslateOperand(HLSLCrossCompilerContext* psContext, const Operand* psOperand, uint32_t ui32TOFlag);
int GetMaxComponentFromComponentMask(const Operand* psOperand);
void TranslateOperandIndex(HLSLCrossCompilerContext* psContext, const Operand* psOperand, int index);
void TranslateOperandIndexMAD(HLSLCrossCompilerContext* psContext, const Operand* psOperand, int index, uint32_t multiply, uint32_t add);
void TranslateVariableName(HLSLCrossCompilerContext* psContext, const Operand* psOperand, uint32_t ui32TOFlag, uint32_t* pui32IgnoreSwizzle);
void TranslateOperandSwizzle(HLSLCrossCompilerContext* psContext, const Operand* psOperand);
uint32_t GetNumSwizzleElements(const Operand* psOperand);
void AddSwizzleUsingElementCount(HLSLCrossCompilerContext* psContext, uint32_t count);
int GetFirstOperandSwizzle(HLSLCrossCompilerContext* psContext, const Operand* psOperand);
uint32_t IsSwizzleReplacated(const Operand* psOperand);
void TextureName(bstring output, Shader* psShader, const uint32_t ui32TextureRegister, const uint32_t ui32SamplerRegister, const int bCompare);
void UAVName(bstring output, Shader* psShader, const uint32_t ui32RegisterNumber);
void UniformBufferName(bstring output, Shader* psShader, const uint32_t ui32RegisterNumber);
void ConvertToTextureName(bstring output, Shader* psShader, const char* szName, const char* szSamplerName, const int bCompare);
void ConvertToUAVName(bstring output, Shader* psShader, const char* szOriginalUAVName);
void ConvertToUniformBufferName(bstring output, Shader* psShader, const char* szConstantBufferName);
void ShaderVarName(bstring output, Shader* psShader, const char* OriginalName);
void ShaderVarFullName(bstring output, Shader* psShader, const ShaderVarType* psShaderVar);
uint32_t ConvertOperandSwizzleToComponentMask(const Operand* psOperand);
//Non-zero means the components overlap
int CompareOperandSwizzles(const Operand* psOperandA, const Operand* psOperandB);
SHADER_VARIABLE_TYPE GetOperandDataType(HLSLCrossCompilerContext* psContext, const Operand* psOperand);
// NOTE: CODE DUPLICATION FROM HLSLcc METAL ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void TranslateGmemOperandSwizzleWithMask(HLSLCrossCompilerContext* psContext, const Operand* psOperand, uint32_t ui32ComponentMask, uint32_t gmemNumElements);
uint32_t GetGmemInputResourceSlot(uint32_t const slotIn);
uint32_t GetGmemInputResourceNumElements(uint32_t const slotIn);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#endif
@@ -0,0 +1,16 @@
// Modifications copyright Amazon.com, Inc. or its affiliates
// Modifications copyright Crytek GmbH
#ifndef TO_METAL_DECLARATION_H
#define TO_METAL_DECLARATION_H
#include "internal_includes/structs.h"
void TranslateDeclarationMETAL(HLSLCrossCompilerContext* psContext, const Declaration* psDecl);
char* GetDeclaredInputNameMETAL(const HLSLCrossCompilerContext* psContext, const SHADER_TYPE eShaderType, const Operand* psOperand);
char* GetDeclaredOutputNameMETAL(const HLSLCrossCompilerContext* psContext, const SHADER_TYPE eShaderType, const Operand* psOperand);
const char* GetMangleSuffixMETAL(const SHADER_TYPE eShaderType);
#endif
@@ -0,0 +1,18 @@
// Modifications copyright Amazon.com, Inc. or its affiliates
// Modifications copyright Crytek GmbH
#ifndef TO_METAL_INSTRUCTION_H
#define TO_METAL_INSTRUCTION_H
#include "internal_includes/structs.h"
void TranslateInstructionMETAL(HLSLCrossCompilerContext* psContext, Instruction* psInst);
//For each MOV temp, immediate; check to see if the next instruction
//using that temp has an integer opcode. If so then the immediate value
//is flaged as having an integer encoding.
void MarkIntegerImmediatesMETAL(HLSLCrossCompilerContext* psContext);
void SetDataTypesMETAL(HLSLCrossCompilerContext* psContext, Instruction* psInst, const int32_t i32InstCount, SHADER_VARIABLE_TYPE* aeCommonTempVecType);
#endif
@@ -0,0 +1,38 @@
// Modifications copyright Amazon.com, Inc. or its affiliates
// Modifications copyright Crytek GmbH
#ifndef TO_METAL_OPERAND_H
#define TO_METAL_OPERAND_H
#include "internal_includes/structs.h"
#define TO_FLAG_NONE 0x0
#define TO_FLAG_INTEGER 0x1
#define TO_FLAG_NAME_ONLY 0x2
#define TO_FLAG_DECLARATION_NAME 0x4
#define TO_FLAG_DESTINATION 0x8 //Operand is being written to by assignment.
#define TO_FLAG_UNSIGNED_INTEGER 0x10
#define TO_FLAG_DOUBLE 0x20
#define TO_FLAG_FLOAT 0x40
void TranslateOperandMETAL(HLSLCrossCompilerContext* psContext, const Operand* psOperand, uint32_t ui32TOFlag);
int GetMaxComponentFromComponentMaskMETAL(const Operand* psOperand);
void TranslateOperandMETALIndex(HLSLCrossCompilerContext* psContext, const Operand* psOperand, int index);
void TranslateOperandMETALIndexMAD(HLSLCrossCompilerContext* psContext, const Operand* psOperand, int index, uint32_t multiply, uint32_t add);
void TranslateVariableNameMETAL(HLSLCrossCompilerContext* psContext, const Operand* psOperand, uint32_t ui32TOFlag, uint32_t* pui32IgnoreSwizzle);
void TranslateOperandMETALSwizzle(HLSLCrossCompilerContext* psContext, const Operand* psOperand);
uint32_t GetNumSwizzleElementsMETAL(const Operand* psOperand);
void AddSwizzleUsingElementCountMETAL(HLSLCrossCompilerContext* psContext, uint32_t count);
int GetFirstOperandSwizzleMETAL(HLSLCrossCompilerContext* psContext, const Operand* psOperand);
uint32_t IsSwizzleReplacatedMETAL(const Operand* psOperand);
void TextureNameMETAL(HLSLCrossCompilerContext* psContext, const uint32_t ui32RegisterNumber, const int bZCompare);
uint32_t ConvertOperandSwizzleToComponentMaskMETAL(const Operand* psOperand);
//Non-zero means the components overlap
int CompareOperandSwizzlesMETAL(const Operand* psOperandA, const Operand* psOperandB);
SHADER_VARIABLE_TYPE GetOperandDataTypeMETAL(HLSLCrossCompilerContext* psContext, const Operand* psOperand);
#endif
@@ -0,0 +1,812 @@
// Modifications copyright Amazon.com, Inc. or its affiliates
// Modifications copyright Crytek GmbH
#ifndef TOKENS_H
#define TOKENS_H
#include "hlslcc.h"
typedef enum
{
INVALID_SHADER = -1,
PIXEL_SHADER,
VERTEX_SHADER,
GEOMETRY_SHADER,
HULL_SHADER,
DOMAIN_SHADER,
COMPUTE_SHADER,
} SHADER_TYPE;
static SHADER_TYPE DecodeShaderType(uint32_t ui32Token)
{
return (SHADER_TYPE)((ui32Token & 0xffff0000) >> 16);
}
static uint32_t DecodeProgramMajorVersion(uint32_t ui32Token)
{
return (ui32Token & 0x000000f0) >> 4;
}
static uint32_t DecodeProgramMinorVersion(uint32_t ui32Token)
{
return (ui32Token & 0x0000000f);
}
static uint32_t DecodeInstructionLength(uint32_t ui32Token)
{
return (ui32Token & 0x7f000000) >> 24;
}
static uint32_t DecodeIsOpcodeExtended(uint32_t ui32Token)
{
return (ui32Token & 0x80000000) >> 31;
}
typedef enum EXTENDED_OPCODE_TYPE
{
EXTENDED_OPCODE_EMPTY = 0,
EXTENDED_OPCODE_SAMPLE_CONTROLS = 1,
EXTENDED_OPCODE_RESOURCE_DIM = 2,
EXTENDED_OPCODE_RESOURCE_RETURN_TYPE = 3,
} EXTENDED_OPCODE_TYPE;
static EXTENDED_OPCODE_TYPE DecodeExtendedOpcodeType(uint32_t ui32Token)
{
return (EXTENDED_OPCODE_TYPE)(ui32Token & 0x0000003f);
}
typedef enum RESOURCE_RETURN_TYPE
{
RETURN_TYPE_UNORM = 1,
RETURN_TYPE_SNORM = 2,
RETURN_TYPE_SINT = 3,
RETURN_TYPE_UINT = 4,
RETURN_TYPE_FLOAT = 5,
RETURN_TYPE_MIXED = 6,
RETURN_TYPE_DOUBLE = 7,
RETURN_TYPE_CONTINUED = 8,
RETURN_TYPE_UNUSED = 9,
} RESOURCE_RETURN_TYPE;
static RESOURCE_RETURN_TYPE DecodeResourceReturnType(uint32_t ui32Coord, uint32_t ui32Token)
{
return (RESOURCE_RETURN_TYPE)((ui32Token>>(ui32Coord * 4))&0xF);
}
static RESOURCE_RETURN_TYPE DecodeExtendedResourceReturnType(uint32_t ui32Coord, uint32_t ui32Token)
{
return (RESOURCE_RETURN_TYPE)((ui32Token>>(ui32Coord * 4 + 6))&0xF);
}
typedef enum
{
//For DX9
OPCODE_POW = -6,
OPCODE_DP2ADD = -5,
OPCODE_LRP = -4,
OPCODE_ENDREP = -3,
OPCODE_REP = -2,
OPCODE_SPECIAL_DCL_IMMCONST = -1,
OPCODE_ADD,
OPCODE_AND,
OPCODE_BREAK,
OPCODE_BREAKC,
OPCODE_CALL,
OPCODE_CALLC,
OPCODE_CASE,
OPCODE_CONTINUE,
OPCODE_CONTINUEC,
OPCODE_CUT,
OPCODE_DEFAULT,
OPCODE_DERIV_RTX,
OPCODE_DERIV_RTY,
OPCODE_DISCARD,
OPCODE_DIV,
OPCODE_DP2,
OPCODE_DP3,
OPCODE_DP4,
OPCODE_ELSE,
OPCODE_EMIT,
OPCODE_EMITTHENCUT,
OPCODE_ENDIF,
OPCODE_ENDLOOP,
OPCODE_ENDSWITCH,
OPCODE_EQ,
OPCODE_EXP,
OPCODE_FRC,
OPCODE_FTOI,
OPCODE_FTOU,
OPCODE_GE,
OPCODE_IADD,
OPCODE_IF,
OPCODE_IEQ,
OPCODE_IGE,
OPCODE_ILT,
OPCODE_IMAD,
OPCODE_IMAX,
OPCODE_IMIN,
OPCODE_IMUL,
OPCODE_INE,
OPCODE_INEG,
OPCODE_ISHL,
OPCODE_ISHR,
OPCODE_ITOF,
OPCODE_LABEL,
OPCODE_LD,
OPCODE_LD_MS,
OPCODE_LOG,
OPCODE_LOOP,
OPCODE_LT,
OPCODE_MAD,
OPCODE_MIN,
OPCODE_MAX,
OPCODE_CUSTOMDATA,
OPCODE_MOV,
OPCODE_MOVC,
OPCODE_MUL,
OPCODE_NE,
OPCODE_NOP,
OPCODE_NOT,
OPCODE_OR,
OPCODE_RESINFO,
OPCODE_RET,
OPCODE_RETC,
OPCODE_ROUND_NE,
OPCODE_ROUND_NI,
OPCODE_ROUND_PI,
OPCODE_ROUND_Z,
OPCODE_RSQ,
OPCODE_SAMPLE,
OPCODE_SAMPLE_C,
OPCODE_SAMPLE_C_LZ,
OPCODE_SAMPLE_L,
OPCODE_SAMPLE_D,
OPCODE_SAMPLE_B,
OPCODE_SQRT,
OPCODE_SWITCH,
OPCODE_SINCOS,
OPCODE_UDIV,
OPCODE_ULT,
OPCODE_UGE,
OPCODE_UMUL,
OPCODE_UMAD,
OPCODE_UMAX,
OPCODE_UMIN,
OPCODE_USHR,
OPCODE_UTOF,
OPCODE_XOR,
OPCODE_DCL_RESOURCE, // DCL* opcodes have
OPCODE_DCL_CONSTANT_BUFFER, // custom operand formats.
OPCODE_DCL_SAMPLER,
OPCODE_DCL_INDEX_RANGE,
OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY,
OPCODE_DCL_GS_INPUT_PRIMITIVE,
OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT,
OPCODE_DCL_INPUT,
OPCODE_DCL_INPUT_SGV,
OPCODE_DCL_INPUT_SIV,
OPCODE_DCL_INPUT_PS,
OPCODE_DCL_INPUT_PS_SGV,
OPCODE_DCL_INPUT_PS_SIV,
OPCODE_DCL_OUTPUT,
OPCODE_DCL_OUTPUT_SGV,
OPCODE_DCL_OUTPUT_SIV,
OPCODE_DCL_TEMPS,
OPCODE_DCL_INDEXABLE_TEMP,
OPCODE_DCL_GLOBAL_FLAGS,
// -----------------------------------------------
OPCODE_RESERVED_10,
// ---------- DX 10.1 op codes---------------------
OPCODE_LOD,
OPCODE_GATHER4,
OPCODE_SAMPLE_POS,
OPCODE_SAMPLE_INFO,
// -----------------------------------------------
// This should be 10.1's version of NUM_OPCODES
OPCODE_RESERVED_10_1,
// ---------- DX 11 op codes---------------------
OPCODE_HS_DECLS, // token marks beginning of HS sub-shader
OPCODE_HS_CONTROL_POINT_PHASE, // token marks beginning of HS sub-shader
OPCODE_HS_FORK_PHASE, // token marks beginning of HS sub-shader
OPCODE_HS_JOIN_PHASE, // token marks beginning of HS sub-shader
OPCODE_EMIT_STREAM,
OPCODE_CUT_STREAM,
OPCODE_EMITTHENCUT_STREAM,
OPCODE_INTERFACE_CALL,
OPCODE_BUFINFO,
OPCODE_DERIV_RTX_COARSE,
OPCODE_DERIV_RTX_FINE,
OPCODE_DERIV_RTY_COARSE,
OPCODE_DERIV_RTY_FINE,
OPCODE_GATHER4_C,
OPCODE_GATHER4_PO,
OPCODE_GATHER4_PO_C,
OPCODE_RCP,
OPCODE_F32TOF16,
OPCODE_F16TOF32,
OPCODE_UADDC,
OPCODE_USUBB,
OPCODE_COUNTBITS,
OPCODE_FIRSTBIT_HI,
OPCODE_FIRSTBIT_LO,
OPCODE_FIRSTBIT_SHI,
OPCODE_UBFE,
OPCODE_IBFE,
OPCODE_BFI,
OPCODE_BFREV,
OPCODE_SWAPC,
OPCODE_DCL_STREAM,
OPCODE_DCL_FUNCTION_BODY,
OPCODE_DCL_FUNCTION_TABLE,
OPCODE_DCL_INTERFACE,
OPCODE_DCL_INPUT_CONTROL_POINT_COUNT,
OPCODE_DCL_OUTPUT_CONTROL_POINT_COUNT,
OPCODE_DCL_TESS_DOMAIN,
OPCODE_DCL_TESS_PARTITIONING,
OPCODE_DCL_TESS_OUTPUT_PRIMITIVE,
OPCODE_DCL_HS_MAX_TESSFACTOR,
OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT,
OPCODE_DCL_HS_JOIN_PHASE_INSTANCE_COUNT,
OPCODE_DCL_THREAD_GROUP,
OPCODE_DCL_UNORDERED_ACCESS_VIEW_TYPED,
OPCODE_DCL_UNORDERED_ACCESS_VIEW_RAW,
OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED,
OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_RAW,
OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED,
OPCODE_DCL_RESOURCE_RAW,
OPCODE_DCL_RESOURCE_STRUCTURED,
OPCODE_LD_UAV_TYPED,
OPCODE_STORE_UAV_TYPED,
OPCODE_LD_RAW,
OPCODE_STORE_RAW,
OPCODE_LD_STRUCTURED,
OPCODE_STORE_STRUCTURED,
OPCODE_ATOMIC_AND,
OPCODE_ATOMIC_OR,
OPCODE_ATOMIC_XOR,
OPCODE_ATOMIC_CMP_STORE,
OPCODE_ATOMIC_IADD,
OPCODE_ATOMIC_IMAX,
OPCODE_ATOMIC_IMIN,
OPCODE_ATOMIC_UMAX,
OPCODE_ATOMIC_UMIN,
OPCODE_IMM_ATOMIC_ALLOC,
OPCODE_IMM_ATOMIC_CONSUME,
OPCODE_IMM_ATOMIC_IADD,
OPCODE_IMM_ATOMIC_AND,
OPCODE_IMM_ATOMIC_OR,
OPCODE_IMM_ATOMIC_XOR,
OPCODE_IMM_ATOMIC_EXCH,
OPCODE_IMM_ATOMIC_CMP_EXCH,
OPCODE_IMM_ATOMIC_IMAX,
OPCODE_IMM_ATOMIC_IMIN,
OPCODE_IMM_ATOMIC_UMAX,
OPCODE_IMM_ATOMIC_UMIN,
OPCODE_SYNC,
OPCODE_DADD,
OPCODE_DMAX,
OPCODE_DMIN,
OPCODE_DMUL,
OPCODE_DEQ,
OPCODE_DGE,
OPCODE_DLT,
OPCODE_DNE,
OPCODE_DMOV,
OPCODE_DMOVC,
OPCODE_DTOF,
OPCODE_FTOD,
OPCODE_EVAL_SNAPPED,
OPCODE_EVAL_SAMPLE_INDEX,
OPCODE_EVAL_CENTROID,
OPCODE_DCL_GS_INSTANCE_COUNT,
OPCODE_ABORT,
OPCODE_DEBUG_BREAK,
// -----------------------------------------------
// This marks the end of D3D11.0 opcodes
OPCODE_RESERVED_11,
OPCODE_DDIV,
OPCODE_DFMA,
OPCODE_DRCP,
OPCODE_MSAD,
OPCODE_DTOI,
OPCODE_DTOU,
OPCODE_ITOD,
OPCODE_UTOD,
// -----------------------------------------------
// This marks the end of D3D11.1 opcodes
OPCODE_RESERVED_11_1,
NUM_OPCODES,
OPCODE_INVAILD = NUM_OPCODES,
} OPCODE_TYPE;
static OPCODE_TYPE DecodeOpcodeType(uint32_t ui32Token)
{
return (OPCODE_TYPE)(ui32Token & 0x00007ff);
}
typedef enum
{
INDEX_0D,
INDEX_1D,
INDEX_2D,
INDEX_3D,
} OPERAND_INDEX_DIMENSION;
static OPERAND_INDEX_DIMENSION DecodeOperandIndexDimension(uint32_t ui32Token)
{
return (OPERAND_INDEX_DIMENSION)((ui32Token & 0x00300000) >> 20);
}
typedef enum OPERAND_TYPE
{
OPERAND_TYPE_SPECIAL_LOOPCOUNTER = -10,
OPERAND_TYPE_SPECIAL_IMMCONSTINT = -9,
OPERAND_TYPE_SPECIAL_TEXCOORD = -8,
OPERAND_TYPE_SPECIAL_POSITION = -7,
OPERAND_TYPE_SPECIAL_FOG = -6,
OPERAND_TYPE_SPECIAL_POINTSIZE = -5,
OPERAND_TYPE_SPECIAL_OUTOFFSETCOLOUR = -4,
OPERAND_TYPE_SPECIAL_OUTBASECOLOUR = -3,
OPERAND_TYPE_SPECIAL_ADDRESS = -2,
OPERAND_TYPE_SPECIAL_IMMCONST = -1,
OPERAND_TYPE_TEMP = 0, // Temporary Register File
OPERAND_TYPE_INPUT = 1, // General Input Register File
OPERAND_TYPE_OUTPUT = 2, // General Output Register File
OPERAND_TYPE_INDEXABLE_TEMP = 3, // Temporary Register File (indexable)
OPERAND_TYPE_IMMEDIATE32 = 4, // 32bit/component immediate value(s)
// If for example, operand token bits
// [01:00]==OPERAND_4_COMPONENT,
// this means that the operand type:
// OPERAND_TYPE_IMMEDIATE32
// results in 4 additional 32bit
// DWORDS present for the operand.
OPERAND_TYPE_IMMEDIATE64 = 5, // 64bit/comp.imm.val(s)HI:LO
OPERAND_TYPE_SAMPLER = 6, // Reference to sampler state
OPERAND_TYPE_RESOURCE = 7, // Reference to memory resource (e.g. texture)
OPERAND_TYPE_CONSTANT_BUFFER= 8, // Reference to constant buffer
OPERAND_TYPE_IMMEDIATE_CONSTANT_BUFFER= 9, // Reference to immediate constant buffer
OPERAND_TYPE_LABEL = 10, // Label
OPERAND_TYPE_INPUT_PRIMITIVEID = 11, // Input primitive ID
OPERAND_TYPE_OUTPUT_DEPTH = 12, // Output Depth
OPERAND_TYPE_NULL = 13, // Null register, used to discard results of operations
// Below Are operands new in DX 10.1
OPERAND_TYPE_RASTERIZER = 14, // DX10.1 Rasterizer register, used to denote the depth/stencil and render target resources
OPERAND_TYPE_OUTPUT_COVERAGE_MASK = 15, // DX10.1 PS output MSAA coverage mask (scalar)
// Below Are operands new in DX 11
OPERAND_TYPE_STREAM = 16, // Reference to GS stream output resource
OPERAND_TYPE_FUNCTION_BODY = 17, // Reference to a function definition
OPERAND_TYPE_FUNCTION_TABLE = 18, // Reference to a set of functions used by a class
OPERAND_TYPE_INTERFACE = 19, // Reference to an interface
OPERAND_TYPE_FUNCTION_INPUT = 20, // Reference to an input parameter to a function
OPERAND_TYPE_FUNCTION_OUTPUT = 21, // Reference to an output parameter to a function
OPERAND_TYPE_OUTPUT_CONTROL_POINT_ID = 22, // HS Control Point phase input saying which output control point ID this is
OPERAND_TYPE_INPUT_FORK_INSTANCE_ID = 23, // HS Fork Phase input instance ID
OPERAND_TYPE_INPUT_JOIN_INSTANCE_ID = 24, // HS Join Phase input instance ID
OPERAND_TYPE_INPUT_CONTROL_POINT = 25, // HS Fork+Join, DS phase input control points (array of them)
OPERAND_TYPE_OUTPUT_CONTROL_POINT = 26, // HS Fork+Join phase output control points (array of them)
OPERAND_TYPE_INPUT_PATCH_CONSTANT = 27, // DS+HSJoin Input Patch Constants (array of them)
OPERAND_TYPE_INPUT_DOMAIN_POINT = 28, // DS Input Domain point
OPERAND_TYPE_THIS_POINTER = 29, // Reference to an interface this pointer
OPERAND_TYPE_UNORDERED_ACCESS_VIEW = 30, // Reference to UAV u#
OPERAND_TYPE_THREAD_GROUP_SHARED_MEMORY = 31, // Reference to Thread Group Shared Memory g#
OPERAND_TYPE_INPUT_THREAD_ID = 32, // Compute Shader Thread ID
OPERAND_TYPE_INPUT_THREAD_GROUP_ID = 33, // Compute Shader Thread Group ID
OPERAND_TYPE_INPUT_THREAD_ID_IN_GROUP = 34, // Compute Shader Thread ID In Thread Group
OPERAND_TYPE_INPUT_COVERAGE_MASK = 35, // Pixel shader coverage mask input
OPERAND_TYPE_INPUT_THREAD_ID_IN_GROUP_FLATTENED = 36, // Compute Shader Thread ID In Group Flattened to a 1D value.
OPERAND_TYPE_INPUT_GS_INSTANCE_ID = 37, // Input GS instance ID
OPERAND_TYPE_OUTPUT_DEPTH_GREATER_EQUAL = 38, // Output Depth, forced to be greater than or equal than current depth
OPERAND_TYPE_OUTPUT_DEPTH_LESS_EQUAL = 39, // Output Depth, forced to be less than or equal to current depth
OPERAND_TYPE_CYCLE_COUNTER = 40, // Cycle counter
} OPERAND_TYPE;
static OPERAND_TYPE DecodeOperandType(uint32_t ui32Token)
{
return (OPERAND_TYPE)((ui32Token & 0x000ff000) >> 12);
}
static SPECIAL_NAME DecodeOperandSpecialName(uint32_t ui32Token)
{
return (SPECIAL_NAME)(ui32Token & 0x0000ffff);
}
typedef enum OPERAND_INDEX_REPRESENTATION
{
OPERAND_INDEX_IMMEDIATE32 = 0, // Extra DWORD
OPERAND_INDEX_IMMEDIATE64 = 1, // 2 Extra DWORDs
// (HI32:LO32)
OPERAND_INDEX_RELATIVE = 2, // Extra operand
OPERAND_INDEX_IMMEDIATE32_PLUS_RELATIVE = 3, // Extra DWORD followed by
// extra operand
OPERAND_INDEX_IMMEDIATE64_PLUS_RELATIVE = 4, // 2 Extra DWORDS
// (HI32:LO32) followed
// by extra operand
} OPERAND_INDEX_REPRESENTATION;
static OPERAND_INDEX_REPRESENTATION DecodeOperandIndexRepresentation(uint32_t ui32Dimension, uint32_t ui32Token)
{
return (OPERAND_INDEX_REPRESENTATION)((ui32Token & (0x3<<(22+3*((ui32Dimension)&3)))) >> (22+3*((ui32Dimension)&3)));
}
typedef enum OPERAND_NUM_COMPONENTS
{
OPERAND_0_COMPONENT = 0,
OPERAND_1_COMPONENT = 1,
OPERAND_4_COMPONENT = 2,
OPERAND_N_COMPONENT = 3 // unused for now
} OPERAND_NUM_COMPONENTS;
static OPERAND_NUM_COMPONENTS DecodeOperandNumComponents(uint32_t ui32Token)
{
return (OPERAND_NUM_COMPONENTS)(ui32Token & 0x00000003);
}
typedef enum OPERAND_4_COMPONENT_SELECTION_MODE
{
OPERAND_4_COMPONENT_MASK_MODE = 0, // mask 4 components
OPERAND_4_COMPONENT_SWIZZLE_MODE = 1, // swizzle 4 components
OPERAND_4_COMPONENT_SELECT_1_MODE = 2, // select 1 of 4 components
} OPERAND_4_COMPONENT_SELECTION_MODE;
static OPERAND_4_COMPONENT_SELECTION_MODE DecodeOperand4CompSelMode(uint32_t ui32Token)
{
return (OPERAND_4_COMPONENT_SELECTION_MODE)((ui32Token & 0x0000000c) >> 2);
}
#define OPERAND_4_COMPONENT_MASK_X 0x00000001
#define OPERAND_4_COMPONENT_MASK_Y 0x00000002
#define OPERAND_4_COMPONENT_MASK_Z 0x00000004
#define OPERAND_4_COMPONENT_MASK_W 0x00000008
#define OPERAND_4_COMPONENT_MASK_R OPERAND_4_COMPONENT_MASK_X
#define OPERAND_4_COMPONENT_MASK_G OPERAND_4_COMPONENT_MASK_Y
#define OPERAND_4_COMPONENT_MASK_B OPERAND_4_COMPONENT_MASK_Z
#define OPERAND_4_COMPONENT_MASK_A OPERAND_4_COMPONENT_MASK_W
#define OPERAND_4_COMPONENT_MASK_ALL 0x0000000f
static uint32_t DecodeOperand4CompMask(uint32_t ui32Token)
{
return (uint32_t)((ui32Token & 0x000000f0) >> 4);
}
static uint32_t DecodeOperand4CompSwizzle(uint32_t ui32Token)
{
return (uint32_t)((ui32Token & 0x00000ff0) >> 4);
}
static uint32_t DecodeOperand4CompSel1(uint32_t ui32Token)
{
return (uint32_t)((ui32Token & 0x00000030) >> 4);
}
#define OPERAND_4_COMPONENT_X 0
#define OPERAND_4_COMPONENT_Y 1
#define OPERAND_4_COMPONENT_Z 2
#define OPERAND_4_COMPONENT_W 3
static uint32_t NO_SWIZZLE = (( (OPERAND_4_COMPONENT_X) | (OPERAND_4_COMPONENT_Y<<2) | (OPERAND_4_COMPONENT_Z << 4) | (OPERAND_4_COMPONENT_W << 6))/*<<4*/);
static uint32_t XXXX_SWIZZLE = (((OPERAND_4_COMPONENT_X) | (OPERAND_4_COMPONENT_X<<2) | (OPERAND_4_COMPONENT_X << 4) | (OPERAND_4_COMPONENT_X << 6)));
static uint32_t YYYY_SWIZZLE = (((OPERAND_4_COMPONENT_Y) | (OPERAND_4_COMPONENT_Y<<2) | (OPERAND_4_COMPONENT_Y << 4) | (OPERAND_4_COMPONENT_Y << 6)));
static uint32_t ZZZZ_SWIZZLE = (((OPERAND_4_COMPONENT_Z) | (OPERAND_4_COMPONENT_Z<<2) | (OPERAND_4_COMPONENT_Z << 4) | (OPERAND_4_COMPONENT_Z << 6)));
static uint32_t WWWW_SWIZZLE = (((OPERAND_4_COMPONENT_W) | (OPERAND_4_COMPONENT_W<<2) | (OPERAND_4_COMPONENT_W << 4) | (OPERAND_4_COMPONENT_W << 6)));
static uint32_t DecodeOperand4CompSwizzleSource(uint32_t ui32Token, uint32_t comp)
{
return (uint32_t)(((ui32Token)>>(4+2*((comp)&3)))&3);
}
typedef enum RESOURCE_DIMENSION
{
RESOURCE_DIMENSION_UNKNOWN = 0,
RESOURCE_DIMENSION_BUFFER = 1,
RESOURCE_DIMENSION_TEXTURE1D = 2,
RESOURCE_DIMENSION_TEXTURE2D = 3,
RESOURCE_DIMENSION_TEXTURE2DMS = 4,
RESOURCE_DIMENSION_TEXTURE3D = 5,
RESOURCE_DIMENSION_TEXTURECUBE = 6,
RESOURCE_DIMENSION_TEXTURE1DARRAY = 7,
RESOURCE_DIMENSION_TEXTURE2DARRAY = 8,
RESOURCE_DIMENSION_TEXTURE2DMSARRAY = 9,
RESOURCE_DIMENSION_TEXTURECUBEARRAY = 10,
RESOURCE_DIMENSION_RAW_BUFFER = 11,
RESOURCE_DIMENSION_STRUCTURED_BUFFER = 12,
} RESOURCE_DIMENSION;
static RESOURCE_DIMENSION DecodeResourceDimension(uint32_t ui32Token)
{
return (RESOURCE_DIMENSION)((ui32Token & 0x0000f800) >> 11);
}
static RESOURCE_DIMENSION DecodeExtendedResourceDimension(uint32_t ui32Token)
{
return (RESOURCE_DIMENSION)((ui32Token & 0x000007C0) >> 6);
}
typedef enum CONSTANT_BUFFER_ACCESS_PATTERN
{
CONSTANT_BUFFER_ACCESS_PATTERN_IMMEDIATEINDEXED = 0,
CONSTANT_BUFFER_ACCESS_PATTERN_DYNAMICINDEXED = 1
} CONSTANT_BUFFER_ACCESS_PATTERN;
static CONSTANT_BUFFER_ACCESS_PATTERN DecodeConstantBufferAccessPattern(uint32_t ui32Token)
{
return (CONSTANT_BUFFER_ACCESS_PATTERN)((ui32Token & 0x00000800) >> 11);
}
typedef enum INSTRUCTION_TEST_BOOLEAN
{
INSTRUCTION_TEST_ZERO = 0,
INSTRUCTION_TEST_NONZERO = 1
} INSTRUCTION_TEST_BOOLEAN;
static INSTRUCTION_TEST_BOOLEAN DecodeInstrTestBool(uint32_t ui32Token)
{
return (INSTRUCTION_TEST_BOOLEAN)((ui32Token & 0x00040000) >> 18);
}
static uint32_t DecodeIsOperandExtended(uint32_t ui32Token)
{
return (ui32Token & 0x80000000) >> 31;
}
typedef enum EXTENDED_OPERAND_TYPE
{
EXTENDED_OPERAND_EMPTY = 0,
EXTENDED_OPERAND_MODIFIER = 1,
} EXTENDED_OPERAND_TYPE;
static EXTENDED_OPERAND_TYPE DecodeExtendedOperandType(uint32_t ui32Token)
{
return (EXTENDED_OPERAND_TYPE)(ui32Token & 0x0000003f);
}
typedef enum OPERAND_MODIFIER
{
OPERAND_MODIFIER_NONE = 0,
OPERAND_MODIFIER_NEG = 1,
OPERAND_MODIFIER_ABS = 2,
OPERAND_MODIFIER_ABSNEG = 3,
} OPERAND_MODIFIER;
static OPERAND_MODIFIER DecodeExtendedOperandModifier(uint32_t ui32Token)
{
return (OPERAND_MODIFIER)((ui32Token & 0x00003fc0) >> 6);
}
static const uint32_t GLOBAL_FLAG_REFACTORING_ALLOWED = (1<<11);
static const uint32_t GLOBAL_FLAG_ENABLE_DOUBLE_PRECISION_FLOAT_OPS = (1<<12);
static const uint32_t GLOBAL_FLAG_FORCE_EARLY_DEPTH_STENCIL = (1<<13);
static const uint32_t GLOBAL_FLAG_ENABLE_RAW_AND_STRUCTURED_BUFFERS = (1<<14);
static const uint32_t GLOBAL_FLAG_SKIP_OPTIMIZATION = (1<<15);
static const uint32_t GLOBAL_FLAG_ENABLE_MINIMUM_PRECISION = (1<<16);
static const uint32_t GLOBAL_FLAG_ENABLE_DOUBLE_EXTENSIONS = (1<<17);
static const uint32_t GLOBAL_FLAG_ENABLE_SHADER_EXTENSIONS = (1<<18);
static uint32_t DecodeGlobalFlags(uint32_t ui32Token)
{
return (uint32_t)(ui32Token & 0x00fff800);
}
static INTERPOLATION_MODE DecodeInterpolationMode(uint32_t ui32Token)
{
return (INTERPOLATION_MODE)((ui32Token & 0x00007800) >> 11);
}
typedef enum PRIMITIVE_TOPOLOGY
{
PRIMITIVE_TOPOLOGY_UNDEFINED = 0,
PRIMITIVE_TOPOLOGY_POINTLIST = 1,
PRIMITIVE_TOPOLOGY_LINELIST = 2,
PRIMITIVE_TOPOLOGY_LINESTRIP = 3,
PRIMITIVE_TOPOLOGY_TRIANGLELIST = 4,
PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = 5,
// 6 is reserved for legacy triangle fans
// Adjacency values should be equal to (0x8 & non-adjacency):
PRIMITIVE_TOPOLOGY_LINELIST_ADJ = 10,
PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ = 11,
PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ = 12,
PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ = 13,
} PRIMITIVE_TOPOLOGY;
static PRIMITIVE_TOPOLOGY DecodeGSOutputPrimitiveTopology(uint32_t ui32Token)
{
return (PRIMITIVE_TOPOLOGY)((ui32Token & 0x0001f800) >> 11);
}
typedef enum PRIMITIVE
{
PRIMITIVE_UNDEFINED = 0,
PRIMITIVE_POINT = 1,
PRIMITIVE_LINE = 2,
PRIMITIVE_TRIANGLE = 3,
// Adjacency values should be equal to (0x4 & non-adjacency):
PRIMITIVE_LINE_ADJ = 6,
PRIMITIVE_TRIANGLE_ADJ = 7,
PRIMITIVE_1_CONTROL_POINT_PATCH = 8,
PRIMITIVE_2_CONTROL_POINT_PATCH = 9,
PRIMITIVE_3_CONTROL_POINT_PATCH = 10,
PRIMITIVE_4_CONTROL_POINT_PATCH = 11,
PRIMITIVE_5_CONTROL_POINT_PATCH = 12,
PRIMITIVE_6_CONTROL_POINT_PATCH = 13,
PRIMITIVE_7_CONTROL_POINT_PATCH = 14,
PRIMITIVE_8_CONTROL_POINT_PATCH = 15,
PRIMITIVE_9_CONTROL_POINT_PATCH = 16,
PRIMITIVE_10_CONTROL_POINT_PATCH = 17,
PRIMITIVE_11_CONTROL_POINT_PATCH = 18,
PRIMITIVE_12_CONTROL_POINT_PATCH = 19,
PRIMITIVE_13_CONTROL_POINT_PATCH = 20,
PRIMITIVE_14_CONTROL_POINT_PATCH = 21,
PRIMITIVE_15_CONTROL_POINT_PATCH = 22,
PRIMITIVE_16_CONTROL_POINT_PATCH = 23,
PRIMITIVE_17_CONTROL_POINT_PATCH = 24,
PRIMITIVE_18_CONTROL_POINT_PATCH = 25,
PRIMITIVE_19_CONTROL_POINT_PATCH = 26,
PRIMITIVE_20_CONTROL_POINT_PATCH = 27,
PRIMITIVE_21_CONTROL_POINT_PATCH = 28,
PRIMITIVE_22_CONTROL_POINT_PATCH = 29,
PRIMITIVE_23_CONTROL_POINT_PATCH = 30,
PRIMITIVE_24_CONTROL_POINT_PATCH = 31,
PRIMITIVE_25_CONTROL_POINT_PATCH = 32,
PRIMITIVE_26_CONTROL_POINT_PATCH = 33,
PRIMITIVE_27_CONTROL_POINT_PATCH = 34,
PRIMITIVE_28_CONTROL_POINT_PATCH = 35,
PRIMITIVE_29_CONTROL_POINT_PATCH = 36,
PRIMITIVE_30_CONTROL_POINT_PATCH = 37,
PRIMITIVE_31_CONTROL_POINT_PATCH = 38,
PRIMITIVE_32_CONTROL_POINT_PATCH = 39,
} PRIMITIVE;
static PRIMITIVE DecodeGSInputPrimitive(uint32_t ui32Token)
{
return (PRIMITIVE)((ui32Token & 0x0001f800) >> 11);
}
static TESSELLATOR_PARTITIONING DecodeTessPartitioning(uint32_t ui32Token)
{
return (TESSELLATOR_PARTITIONING)((ui32Token & 0x00003800) >> 11);
}
typedef enum TESSELLATOR_DOMAIN
{
TESSELLATOR_DOMAIN_UNDEFINED = 0,
TESSELLATOR_DOMAIN_ISOLINE = 1,
TESSELLATOR_DOMAIN_TRI = 2,
TESSELLATOR_DOMAIN_QUAD = 3
} TESSELLATOR_DOMAIN;
static TESSELLATOR_DOMAIN DecodeTessDomain(uint32_t ui32Token)
{
return (TESSELLATOR_DOMAIN)((ui32Token & 0x00001800) >> 11);
}
static TESSELLATOR_OUTPUT_PRIMITIVE DecodeTessOutPrim(uint32_t ui32Token)
{
return (TESSELLATOR_OUTPUT_PRIMITIVE)((ui32Token & 0x00003800) >> 11);
}
static const uint32_t SYNC_THREADS_IN_GROUP = 0x00000800;
static const uint32_t SYNC_THREAD_GROUP_SHARED_MEMORY = 0x00001000;
static const uint32_t SYNC_UNORDERED_ACCESS_VIEW_MEMORY_GROUP = 0x00002000;
static const uint32_t SYNC_UNORDERED_ACCESS_VIEW_MEMORY_GLOBAL = 0x00004000;
static uint32_t DecodeSyncFlags(uint32_t ui32Token)
{
return ui32Token & 0x00007800;
}
// The number of types that implement this interface
static uint32_t DecodeInterfaceTableLength(uint32_t ui32Token)
{
return (uint32_t)((ui32Token & 0x0000ffff) >> 0);
}
// The number of interfaces that are defined in this array.
static uint32_t DecodeInterfaceArrayLength(uint32_t ui32Token)
{
return (uint32_t)((ui32Token & 0xffff0000) >> 16);
}
typedef enum CUSTOMDATA_CLASS
{
CUSTOMDATA_COMMENT = 0,
CUSTOMDATA_DEBUGINFO,
CUSTOMDATA_OPAQUE,
CUSTOMDATA_DCL_IMMEDIATE_CONSTANT_BUFFER,
CUSTOMDATA_SHADER_MESSAGE,
} CUSTOMDATA_CLASS;
static CUSTOMDATA_CLASS DecodeCustomDataClass(uint32_t ui32Token)
{
return (CUSTOMDATA_CLASS)((ui32Token & 0xfffff800) >> 11);
}
static uint32_t DecodeInstructionSaturate(uint32_t ui32Token)
{
return (ui32Token & 0x00002000) ? 1 : 0;
}
typedef enum OPERAND_MIN_PRECISION
{
OPERAND_MIN_PRECISION_DEFAULT = 0, // Default precision
// for the shader model
OPERAND_MIN_PRECISION_FLOAT_16 = 1, // Min 16 bit/component float
OPERAND_MIN_PRECISION_FLOAT_2_8 = 2, // Min 10(2.8)bit/comp. float
OPERAND_MIN_PRECISION_SINT_16 = 4, // Min 16 bit/comp. signed integer
OPERAND_MIN_PRECISION_UINT_16 = 5, // Min 16 bit/comp. unsigned integer
} OPERAND_MIN_PRECISION;
static uint32_t DecodeOperandMinPrecision(uint32_t ui32Token)
{
return (ui32Token & 0x0001C000) >> 14;
}
static uint32_t DecodeOutputControlPointCount(uint32_t ui32Token)
{
return ((ui32Token & 0x0001f800) >> 11);
}
typedef enum IMMEDIATE_ADDRESS_OFFSET_COORD
{
IMMEDIATE_ADDRESS_OFFSET_U = 0,
IMMEDIATE_ADDRESS_OFFSET_V = 1,
IMMEDIATE_ADDRESS_OFFSET_W = 2,
} IMMEDIATE_ADDRESS_OFFSET_COORD;
#define IMMEDIATE_ADDRESS_OFFSET_SHIFT(Coord) (9+4*((Coord)&3))
#define IMMEDIATE_ADDRESS_OFFSET_MASK(Coord) (0x0000000f<<IMMEDIATE_ADDRESS_OFFSET_SHIFT(Coord))
static uint32_t DecodeImmediateAddressOffset(IMMEDIATE_ADDRESS_OFFSET_COORD eCoord, uint32_t ui32Token)
{
return ((((ui32Token)&IMMEDIATE_ADDRESS_OFFSET_MASK(eCoord))>>(IMMEDIATE_ADDRESS_OFFSET_SHIFT(eCoord))));
}
// UAV access scope flags
static const uint32_t GLOBALLY_COHERENT_ACCESS = 0x00010000;
static uint32_t DecodeAccessCoherencyFlags(uint32_t ui32Token)
{
return ui32Token & 0x00010000;
}
typedef enum RESINFO_RETURN_TYPE
{
RESINFO_INSTRUCTION_RETURN_FLOAT = 0,
RESINFO_INSTRUCTION_RETURN_RCPFLOAT = 1,
RESINFO_INSTRUCTION_RETURN_UINT = 2
} RESINFO_RETURN_TYPE;
static RESINFO_RETURN_TYPE DecodeResInfoReturnType(uint32_t ui32Token)
{
return (RESINFO_RETURN_TYPE)((ui32Token & 0x00001800) >> 11);
}
#include "tokensDX9.h"
#endif
@@ -0,0 +1,304 @@
// Modifications copyright Amazon.com, Inc. or its affiliates
// Modifications copyright Crytek GmbH
#include "debug.h"
static const uint32_t D3D9SHADER_TYPE_VERTEX = 0xFFFE0000;
static const uint32_t D3D9SHADER_TYPE_PIXEL = 0xFFFF0000;
static SHADER_TYPE DecodeShaderTypeDX9(const uint32_t ui32Token)
{
uint32_t ui32Type = ui32Token & 0xFFFF0000;
if(ui32Type == D3D9SHADER_TYPE_VERTEX)
return VERTEX_SHADER;
if(ui32Type == D3D9SHADER_TYPE_PIXEL)
return PIXEL_SHADER;
return INVALID_SHADER;
}
static uint32_t DecodeProgramMajorVersionDX9(const uint32_t ui32Token)
{
return ((ui32Token)>>8)&0xFF;
}
static uint32_t DecodeProgramMinorVersionDX9(const uint32_t ui32Token)
{
return ui32Token & 0xFF;
}
typedef enum
{
OPCODE_DX9_NOP = 0,
OPCODE_DX9_MOV ,
OPCODE_DX9_ADD ,
OPCODE_DX9_SUB ,
OPCODE_DX9_MAD ,
OPCODE_DX9_MUL ,
OPCODE_DX9_RCP ,
OPCODE_DX9_RSQ ,
OPCODE_DX9_DP3 ,
OPCODE_DX9_DP4 ,
OPCODE_DX9_MIN ,
OPCODE_DX9_MAX ,
OPCODE_DX9_SLT ,
OPCODE_DX9_SGE ,
OPCODE_DX9_EXP ,
OPCODE_DX9_LOG ,
OPCODE_DX9_LIT ,
OPCODE_DX9_DST ,
OPCODE_DX9_LRP ,
OPCODE_DX9_FRC ,
OPCODE_DX9_M4x4 ,
OPCODE_DX9_M4x3 ,
OPCODE_DX9_M3x4 ,
OPCODE_DX9_M3x3 ,
OPCODE_DX9_M3x2 ,
OPCODE_DX9_CALL ,
OPCODE_DX9_CALLNZ ,
OPCODE_DX9_LOOP ,
OPCODE_DX9_RET ,
OPCODE_DX9_ENDLOOP ,
OPCODE_DX9_LABEL ,
OPCODE_DX9_DCL ,
OPCODE_DX9_POW ,
OPCODE_DX9_CRS ,
OPCODE_DX9_SGN ,
OPCODE_DX9_ABS ,
OPCODE_DX9_NRM ,
OPCODE_DX9_SINCOS ,
OPCODE_DX9_REP ,
OPCODE_DX9_ENDREP ,
OPCODE_DX9_IF ,
OPCODE_DX9_IFC ,
OPCODE_DX9_ELSE ,
OPCODE_DX9_ENDIF ,
OPCODE_DX9_BREAK ,
OPCODE_DX9_BREAKC ,
OPCODE_DX9_MOVA ,
OPCODE_DX9_DEFB ,
OPCODE_DX9_DEFI ,
OPCODE_DX9_TEXCOORD = 64,
OPCODE_DX9_TEXKILL ,
OPCODE_DX9_TEX ,
OPCODE_DX9_TEXBEM ,
OPCODE_DX9_TEXBEML ,
OPCODE_DX9_TEXREG2AR ,
OPCODE_DX9_TEXREG2GB ,
OPCODE_DX9_TEXM3x2PAD ,
OPCODE_DX9_TEXM3x2TEX ,
OPCODE_DX9_TEXM3x3PAD ,
OPCODE_DX9_TEXM3x3TEX ,
OPCODE_DX9_RESERVED0 ,
OPCODE_DX9_TEXM3x3SPEC ,
OPCODE_DX9_TEXM3x3VSPEC ,
OPCODE_DX9_EXPP ,
OPCODE_DX9_LOGP ,
OPCODE_DX9_CND ,
OPCODE_DX9_DEF ,
OPCODE_DX9_TEXREG2RGB ,
OPCODE_DX9_TEXDP3TEX ,
OPCODE_DX9_TEXM3x2DEPTH ,
OPCODE_DX9_TEXDP3 ,
OPCODE_DX9_TEXM3x3 ,
OPCODE_DX9_TEXDEPTH ,
OPCODE_DX9_CMP ,
OPCODE_DX9_BEM ,
OPCODE_DX9_DP2ADD ,
OPCODE_DX9_DSX ,
OPCODE_DX9_DSY ,
OPCODE_DX9_TEXLDD ,
OPCODE_DX9_SETP ,
OPCODE_DX9_TEXLDL ,
OPCODE_DX9_BREAKP ,
OPCODE_DX9_PHASE = 0xFFFD,
OPCODE_DX9_COMMENT = 0xFFFE,
OPCODE_DX9_END = 0xFFFF,
OPCODE_DX9_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum
} OPCODE_TYPE_DX9;
static OPCODE_TYPE_DX9 DecodeOpcodeTypeDX9(const uint32_t ui32Token)
{
return (OPCODE_TYPE_DX9)(ui32Token & 0x0000FFFF);
}
static uint32_t DecodeInstructionLengthDX9(const uint32_t ui32Token)
{
return (ui32Token & 0x0F000000)>>24;
}
static uint32_t DecodeCommentLengthDX9(const uint32_t ui32Token)
{
return (ui32Token & 0x7FFF0000)>>16;
}
static uint32_t DecodeOperandRegisterNumberDX9(const uint32_t ui32Token)
{
return ui32Token & 0x000007FF;
}
typedef enum
{
OPERAND_TYPE_DX9_TEMP = 0, // Temporary Register File
OPERAND_TYPE_DX9_INPUT = 1, // Input Register File
OPERAND_TYPE_DX9_CONST = 2, // Constant Register File
OPERAND_TYPE_DX9_ADDR = 3, // Address Register (VS)
OPERAND_TYPE_DX9_TEXTURE = 3, // Texture Register File (PS)
OPERAND_TYPE_DX9_RASTOUT = 4, // Rasterizer Register File
OPERAND_TYPE_DX9_ATTROUT = 5, // Attribute Output Register File
OPERAND_TYPE_DX9_TEXCRDOUT = 6, // Texture Coordinate Output Register File
OPERAND_TYPE_DX9_OUTPUT = 6, // Output register file for VS3.0+
OPERAND_TYPE_DX9_CONSTINT = 7, // Constant Integer Vector Register File
OPERAND_TYPE_DX9_COLOROUT = 8, // Color Output Register File
OPERAND_TYPE_DX9_DEPTHOUT = 9, // Depth Output Register File
OPERAND_TYPE_DX9_SAMPLER = 10, // Sampler State Register File
OPERAND_TYPE_DX9_CONST2 = 11, // Constant Register File 2048 - 4095
OPERAND_TYPE_DX9_CONST3 = 12, // Constant Register File 4096 - 6143
OPERAND_TYPE_DX9_CONST4 = 13, // Constant Register File 6144 - 8191
OPERAND_TYPE_DX9_CONSTBOOL = 14, // Constant Boolean register file
OPERAND_TYPE_DX9_LOOP = 15, // Loop counter register file
OPERAND_TYPE_DX9_TEMPFLOAT16 = 16, // 16-bit float temp register file
OPERAND_TYPE_DX9_MISCTYPE = 17, // Miscellaneous (single) registers.
OPERAND_TYPE_DX9_LABEL = 18, // Label
OPERAND_TYPE_DX9_PREDICATE = 19, // Predicate register
OPERAND_TYPE_DX9_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum
} OPERAND_TYPE_DX9;
static OPERAND_TYPE_DX9 DecodeOperandTypeDX9(const uint32_t ui32Token)
{
return (OPERAND_TYPE_DX9)(((ui32Token & 0x70000000) >> 28) |
((ui32Token & 0x00001800) >> 8));
}
static uint32_t CreateOperandTokenDX9(const uint32_t ui32RegNum, const OPERAND_TYPE_DX9 eType)
{
uint32_t ui32Token = ui32RegNum;
ASSERT(ui32RegNum <2048);
ui32Token |= (eType <<28) & 0x70000000;
ui32Token |= (eType <<8) & 0x00001800;
return ui32Token;
}
typedef enum {
DECLUSAGE_POSITION = 0,
DECLUSAGE_BLENDWEIGHT = 1,
DECLUSAGE_BLENDINDICES = 2,
DECLUSAGE_NORMAL = 3,
DECLUSAGE_PSIZE = 4,
DECLUSAGE_TEXCOORD = 5,
DECLUSAGE_TANGENT = 6,
DECLUSAGE_BINORMAL = 7,
DECLUSAGE_TESSFACTOR = 8,
DECLUSAGE_POSITIONT = 9,
DECLUSAGE_COLOR = 10,
DECLUSAGE_FOG = 11,
DECLUSAGE_DEPTH = 12,
DECLUSAGE_SAMPLE = 13
} DECLUSAGE_DX9;
static DECLUSAGE_DX9 DecodeUsageDX9(const uint32_t ui32Token)
{
return (DECLUSAGE_DX9) (ui32Token & 0x0000000f);
}
static uint32_t DecodeUsageIndexDX9(const uint32_t ui32Token)
{
return (ui32Token & 0x000f0000)>>16;
}
static uint32_t DecodeOperandIsRelativeAddressModeDX9(const uint32_t ui32Token)
{
return ui32Token & (1<<13);
}
static const uint32_t DX9_SWIZZLE_SHIFT = 16;
#define NO_SWIZZLE_DX9 ((0<<DX9_SWIZZLE_SHIFT)|(1<<DX9_SWIZZLE_SHIFT)|(2<<DX9_SWIZZLE_SHIFT)|(3<<DX9_SWIZZLE_SHIFT))
#define REPLICATE_SWIZZLE_DX9(CHANNEL) ((CHANNEL<<DX9_SWIZZLE_SHIFT)|(CHANNEL<<(DX9_SWIZZLE_SHIFT+2))|(CHANNEL<<(DX9_SWIZZLE_SHIFT+4))|(CHANNEL<<(DX9_SWIZZLE_SHIFT+6)))
static uint32_t DecodeOperandSwizzleDX9(const uint32_t ui32Token)
{
return ui32Token & 0x00FF0000;
}
static const uint32_t DX9_WRITEMASK_0 = 0x00010000; // Component 0 (X;Red)
static const uint32_t DX9_WRITEMASK_1 = 0x00020000; // Component 1 (Y;Green)
static const uint32_t DX9_WRITEMASK_2 = 0x00040000; // Component 2 (Z;Blue)
static const uint32_t DX9_WRITEMASK_3 = 0x00080000; // Component 3 (W;Alpha)
static const uint32_t DX9_WRITEMASK_ALL = 0x000F0000; // All Components
static uint32_t DecodeDestWriteMaskDX9(const uint32_t ui32Token)
{
return ui32Token & DX9_WRITEMASK_ALL;
}
static RESOURCE_DIMENSION DecodeTextureTypeMaskDX9(const uint32_t ui32Token)
{
switch(ui32Token & 0x78000000)
{
case 2 << 27:
return RESOURCE_DIMENSION_TEXTURE2D;
case 3 << 27:
return RESOURCE_DIMENSION_TEXTURECUBE;
case 4 << 27:
return RESOURCE_DIMENSION_TEXTURE3D;
default:
return RESOURCE_DIMENSION_UNKNOWN;
}
}
static const uint32_t DESTMOD_DX9_NONE = 0;
static const uint32_t DESTMOD_DX9_SATURATE = (1 << 20);
static const uint32_t DESTMOD_DX9_PARTIALPRECISION = (2 << 20);
static const uint32_t DESTMOD_DX9_MSAMPCENTROID = (4 << 20);
static uint32_t DecodeDestModifierDX9(const uint32_t ui32Token)
{
return ui32Token & 0xf00000;
}
typedef enum
{
SRCMOD_DX9_NONE = 0 << 24,
SRCMOD_DX9_NEG = 1 << 24,
SRCMOD_DX9_BIAS = 2 << 24,
SRCMOD_DX9_BIASNEG = 3 << 24,
SRCMOD_DX9_SIGN = 4 << 24,
SRCMOD_DX9_SIGNNEG = 5 << 24,
SRCMOD_DX9_COMP = 6 << 24,
SRCMOD_DX9_X2 = 7 << 24,
SRCMOD_DX9_X2NEG = 8 << 24,
SRCMOD_DX9_DZ = 9 << 24,
SRCMOD_DX9_DW = 10 << 24,
SRCMOD_DX9_ABS = 11 << 24,
SRCMOD_DX9_ABSNEG = 12 << 24,
SRCMOD_DX9_NOT = 13 << 24,
SRCMOD_DX9_FORCE_DWORD = 0xffffffff
} SRCMOD_DX9;
static uint32_t DecodeSrcModifierDX9(const uint32_t ui32Token)
{
return ui32Token & 0xf000000;
}
typedef enum
{
D3DSPC_RESERVED0 = 0,
D3DSPC_GT = 1,
D3DSPC_EQ = 2,
D3DSPC_GE = 3,
D3DSPC_LT = 4,
D3DSPC_NE = 5,
D3DSPC_LE = 6,
D3DSPC_BOOLEAN = 7, //Make use of the RESERVED1 bit to indicate if-bool opcode.
} COMPARISON_DX9;
static COMPARISON_DX9 DecodeComparisonDX9(const uint32_t ui32Token)
{
return (COMPARISON_DX9)((ui32Token & (0x07<<16))>>16);
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff