2016-05-20 13:45:20 -06:00
|
|
|
//
|
|
|
|
//Copyright (C) 2016 LunarG, Inc.
|
|
|
|
//
|
|
|
|
//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 3Dlabs Inc. Ltd. 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 HOLDERS 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.
|
|
|
|
//
|
|
|
|
|
|
|
|
//
|
2017-01-06 00:34:48 -07:00
|
|
|
// Create strings that declare built-in definitions, add built-ins programmatically
|
2016-05-20 13:45:20 -06:00
|
|
|
// that cannot be expressed in the strings, and establish mappings between
|
|
|
|
// built-in functions and operators.
|
|
|
|
//
|
|
|
|
// Where to put a built-in:
|
|
|
|
// TBuiltInParseablesHlsl::initialize(version,profile) context-independent textual built-ins; add them to the right string
|
|
|
|
// TBuiltInParseablesHlsl::initialize(resources,...) context-dependent textual built-ins; add them to the right string
|
|
|
|
// TBuiltInParseablesHlsl::identifyBuiltIns(...,symbolTable) context-independent programmatic additions/mappings to the symbol table,
|
|
|
|
// including identifying what extensions are needed if a version does not allow a symbol
|
|
|
|
// TBuiltInParseablesHlsl::identifyBuiltIns(...,symbolTable, resources) context-dependent programmatic additions/mappings to the
|
|
|
|
// symbol table, including identifying what extensions are needed if a version does
|
|
|
|
// not allow a symbol
|
|
|
|
//
|
|
|
|
|
|
|
|
#include "hlslParseables.h"
|
2016-05-26 10:10:16 -06:00
|
|
|
#include <cctype>
|
|
|
|
#include <utility>
|
2016-07-12 14:45:05 -06:00
|
|
|
#include <algorithm>
|
2016-05-26 10:10:16 -06:00
|
|
|
|
|
|
|
namespace { // anonymous namespace functions
|
|
|
|
|
2016-11-15 10:11:04 -07:00
|
|
|
const bool UseHlslTypes = true;
|
2016-06-20 13:26:59 -06:00
|
|
|
|
2016-07-12 14:45:05 -06:00
|
|
|
const char* BaseTypeName(const char argOrder, const char* scalarName, const char* vecName, const char* matName)
|
2016-05-26 10:10:16 -06:00
|
|
|
{
|
2016-07-12 14:45:05 -06:00
|
|
|
switch (argOrder) {
|
2016-05-26 10:10:16 -06:00
|
|
|
case 'S': return scalarName;
|
|
|
|
case 'V': return vecName;
|
|
|
|
case 'M': return matName;
|
|
|
|
default: return "UNKNOWN_TYPE";
|
|
|
|
}
|
|
|
|
}
|
2016-06-29 10:58:58 -06:00
|
|
|
|
2016-10-04 16:58:14 -06:00
|
|
|
bool IsSamplerType(const char argType) { return argType == 'S' || argType == 's'; }
|
|
|
|
bool IsArrayed(const char argOrder) { return argOrder == '@' || argOrder == '&' || argOrder == '#'; }
|
|
|
|
bool IsTextureMS(const char argOrder) { return argOrder == '$' || argOrder == '&'; }
|
|
|
|
bool IsBuffer(const char argOrder) { return argOrder == '*' || argOrder == '~'; }
|
|
|
|
bool IsImage(const char argOrder) { return argOrder == '!' || argOrder == '#' || argOrder == '~'; }
|
2016-07-27 15:46:48 -06:00
|
|
|
bool IsTextureType(const char argOrder)
|
|
|
|
{
|
2016-10-04 16:58:14 -06:00
|
|
|
return argOrder == '%' || argOrder == '@' || IsTextureMS(argOrder) || IsBuffer(argOrder) | IsImage(argOrder);
|
2016-07-27 15:46:48 -06:00
|
|
|
}
|
2016-07-12 14:45:05 -06:00
|
|
|
|
|
|
|
// Reject certain combinations that are illegal sample methods. For example,
|
|
|
|
// 3D arrays.
|
|
|
|
bool IsIllegalSample(const glslang::TString& name, const char* argOrder, int dim0)
|
2016-06-29 10:58:58 -06:00
|
|
|
{
|
2016-10-04 16:58:14 -06:00
|
|
|
const bool isArrayed = IsArrayed(*argOrder);
|
2016-07-26 15:19:28 -06:00
|
|
|
const bool isMS = IsTextureMS(*argOrder);
|
2016-07-27 15:46:48 -06:00
|
|
|
const bool isBuffer = IsBuffer(*argOrder);
|
2016-07-12 14:45:05 -06:00
|
|
|
|
2016-07-19 14:28:05 -06:00
|
|
|
// there are no 3D arrayed textures, or 3D SampleCmp(LevelZero)
|
|
|
|
if (dim0 == 3 && (isArrayed || name == "SampleCmp" || name == "SampleCmpLevelZero"))
|
2016-07-12 14:45:05 -06:00
|
|
|
return true;
|
|
|
|
|
|
|
|
const int numArgs = int(std::count(argOrder, argOrder + strlen(argOrder), ',')) + 1;
|
|
|
|
|
2016-07-19 14:28:05 -06:00
|
|
|
// Reject invalid offset forms with cubemaps
|
|
|
|
if (dim0 == 4) {
|
2016-07-14 14:45:14 -06:00
|
|
|
if ((name == "Sample" && numArgs >= 4) ||
|
|
|
|
(name == "SampleBias" && numArgs >= 5) ||
|
|
|
|
(name == "SampleCmp" && numArgs >= 5) ||
|
2016-07-19 14:28:05 -06:00
|
|
|
(name == "SampleCmpLevelZero" && numArgs >= 5) ||
|
2016-07-14 14:45:14 -06:00
|
|
|
(name == "SampleGrad" && numArgs >= 6) ||
|
|
|
|
(name == "SampleLevel" && numArgs >= 5))
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-01-06 00:34:48 -07:00
|
|
|
const bool isGather =
|
|
|
|
(name == "Gather" ||
|
2016-07-31 10:37:02 -06:00
|
|
|
name == "GatherRed" ||
|
2017-01-06 00:34:48 -07:00
|
|
|
name == "GatherGreen" ||
|
2016-07-31 10:37:02 -06:00
|
|
|
name == "GatherBlue" ||
|
|
|
|
name == "GatherAlpha");
|
|
|
|
|
2017-01-06 00:34:48 -07:00
|
|
|
const bool isGatherCmp =
|
2016-07-31 10:37:02 -06:00
|
|
|
(name == "GatherCmpRed" ||
|
|
|
|
name == "GatherCmpGreen" ||
|
|
|
|
name == "GatherCmpBlue" ||
|
|
|
|
name == "GatherCmpAlpha");
|
|
|
|
|
2016-07-22 08:28:11 -06:00
|
|
|
// Reject invalid Gathers
|
2016-07-31 10:37:02 -06:00
|
|
|
if (isGather || isGatherCmp) {
|
2016-07-22 08:28:11 -06:00
|
|
|
if (dim0 == 1 || dim0 == 3) // there are no 1D or 3D gathers
|
|
|
|
return true;
|
2016-07-31 10:37:02 -06:00
|
|
|
|
|
|
|
// no offset on cube or cube array gathers
|
|
|
|
if (dim0 == 4) {
|
|
|
|
if ((isGather && numArgs > 3) || (isGatherCmp && numArgs > 4))
|
|
|
|
return true;
|
|
|
|
}
|
2016-07-22 08:28:11 -06:00
|
|
|
}
|
|
|
|
|
2016-07-14 14:45:14 -06:00
|
|
|
// Reject invalid Loads
|
2016-07-19 14:28:05 -06:00
|
|
|
if (name == "Load" && dim0 == 4)
|
|
|
|
return true; // Load does not support any cubemaps, arrayed or not.
|
2016-06-29 10:58:58 -06:00
|
|
|
|
2016-07-26 15:19:28 -06:00
|
|
|
// Multisample formats are only 2D and 2Darray
|
|
|
|
if (isMS && dim0 != 2)
|
|
|
|
return true;
|
|
|
|
|
2016-07-27 15:46:48 -06:00
|
|
|
// Buffer are only 1D
|
|
|
|
if (isBuffer && dim0 != 1)
|
|
|
|
return true;
|
|
|
|
|
2016-07-12 14:45:05 -06:00
|
|
|
return false;
|
|
|
|
}
|
2016-07-19 14:28:05 -06:00
|
|
|
|
|
|
|
// Return the number of the coordinate arg, if any
|
|
|
|
int CoordinateArgPos(const glslang::TString& name, bool isTexture)
|
|
|
|
{
|
|
|
|
if (!isTexture || (name == "GetDimensions"))
|
|
|
|
return -1; // has none
|
|
|
|
else if (name == "Load")
|
|
|
|
return 1;
|
|
|
|
else
|
|
|
|
return 2; // other texture methods are 2
|
|
|
|
}
|
|
|
|
|
|
|
|
// Some texture methods use an addition coordinate dimension for the mip
|
2016-10-04 16:58:14 -06:00
|
|
|
bool HasMipInCoord(const glslang::TString& name, bool isMS, bool isBuffer, bool isImage)
|
2016-07-19 14:28:05 -06:00
|
|
|
{
|
2016-10-04 16:58:14 -06:00
|
|
|
return name == "Load" && !isMS && !isBuffer && !isImage;
|
2016-07-19 14:28:05 -06:00
|
|
|
}
|
|
|
|
|
2016-07-26 08:57:53 -06:00
|
|
|
// LOD calculations don't pass the array level in the coordinate.
|
|
|
|
bool NoArrayCoord(const glslang::TString& name)
|
|
|
|
{
|
|
|
|
return name == "CalculateLevelOfDetail" || name == "CalculateLevelOfDetailUnclamped";
|
|
|
|
}
|
|
|
|
|
2016-07-22 08:28:11 -06:00
|
|
|
// Handle IO params marked with > or <
|
|
|
|
const char* IoParam(glslang::TString& s, const char* nthArgOrder)
|
|
|
|
{
|
|
|
|
if (*nthArgOrder == '>') { // output params
|
|
|
|
++nthArgOrder;
|
|
|
|
s.append("out ");
|
|
|
|
} else if (*nthArgOrder == '<') { // input params
|
|
|
|
++nthArgOrder;
|
|
|
|
s.append("in ");
|
2017-01-06 00:34:48 -07:00
|
|
|
}
|
2016-07-22 08:28:11 -06:00
|
|
|
|
|
|
|
return nthArgOrder;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Handle repeated args
|
|
|
|
void HandleRepeatArg(const char*& arg, const char*& prev, const char* current)
|
|
|
|
{
|
|
|
|
if (*arg == ',' || *arg == '\0')
|
|
|
|
arg = prev;
|
|
|
|
else
|
|
|
|
prev = current;
|
|
|
|
}
|
|
|
|
|
2016-07-26 15:19:28 -06:00
|
|
|
// Return true for the end of a single argument key, which can be the end of the string, or
|
|
|
|
// the comma separator.
|
|
|
|
inline bool IsEndOfArg(const char* arg)
|
|
|
|
{
|
|
|
|
return arg == nullptr || *arg == '\0' || *arg == ',';
|
|
|
|
}
|
|
|
|
|
|
|
|
// If this is a fixed vector size, such as V3, return the size. Else return 0.
|
2017-01-06 00:34:48 -07:00
|
|
|
int FixedVecSize(const char* arg)
|
2016-07-26 15:19:28 -06:00
|
|
|
{
|
|
|
|
while (!IsEndOfArg(arg)) {
|
|
|
|
if (isdigit(*arg))
|
|
|
|
return *arg - '0';
|
|
|
|
++arg;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0; // none found.
|
|
|
|
}
|
|
|
|
|
2016-05-26 10:10:16 -06:00
|
|
|
// Create and return a type name. This is done in GLSL, not HLSL conventions, until such
|
|
|
|
// time as builtins are parsed using the HLSL parser.
|
|
|
|
//
|
|
|
|
// order: S = scalar, V = vector, M = matrix
|
|
|
|
// argType: F = float, D = double, I = int, U = uint, B = bool, S = sampler
|
|
|
|
// dim0 = vector dimension, or matrix 1st dimension
|
|
|
|
// dim1 = matrix 2nd dimension
|
|
|
|
glslang::TString& AppendTypeName(glslang::TString& s, const char* argOrder, const char* argType, int dim0, int dim1)
|
|
|
|
{
|
2016-07-12 14:45:05 -06:00
|
|
|
const bool isTranspose = (argOrder[0] == '^');
|
|
|
|
const bool isTexture = IsTextureType(argOrder[0]);
|
2016-10-04 16:58:14 -06:00
|
|
|
const bool isArrayed = IsArrayed(argOrder[0]);
|
2016-07-22 08:28:11 -06:00
|
|
|
const bool isSampler = IsSamplerType(argType[0]);
|
2016-07-26 15:19:28 -06:00
|
|
|
const bool isMS = IsTextureMS(argOrder[0]);
|
2016-07-27 15:46:48 -06:00
|
|
|
const bool isBuffer = IsBuffer(argOrder[0]);
|
2016-10-04 16:58:14 -06:00
|
|
|
const bool isImage = IsImage(argOrder[0]);
|
2016-07-12 14:45:05 -06:00
|
|
|
|
|
|
|
char type = *argType;
|
2016-05-26 10:10:16 -06:00
|
|
|
|
2016-07-12 14:45:05 -06:00
|
|
|
if (isTranspose) { // Take transpose of matrix dimensions
|
2017-01-06 00:34:48 -07:00
|
|
|
std::swap(dim0, dim1);
|
2016-07-12 14:45:05 -06:00
|
|
|
} else if (isTexture) {
|
|
|
|
if (type == 'F') // map base type to texture of that type.
|
|
|
|
type = 'T'; // e.g, int -> itexture, uint -> utexture, etc.
|
|
|
|
else if (type == 'I')
|
|
|
|
type = 'i';
|
|
|
|
else if (type == 'U')
|
|
|
|
type = 'u';
|
2016-05-26 10:10:16 -06:00
|
|
|
}
|
|
|
|
|
2016-08-24 14:36:13 -06:00
|
|
|
if (isTranspose)
|
2016-07-22 08:28:11 -06:00
|
|
|
++argOrder;
|
|
|
|
|
|
|
|
char order = *argOrder;
|
|
|
|
|
2016-06-20 13:26:59 -06:00
|
|
|
if (UseHlslTypes) {
|
2016-07-12 14:45:05 -06:00
|
|
|
switch (type) {
|
2016-11-15 10:11:04 -07:00
|
|
|
case '-': s += "void"; break;
|
|
|
|
case 'F': s += "float"; break;
|
|
|
|
case 'D': s += "double"; break;
|
|
|
|
case 'I': s += "int"; break;
|
|
|
|
case 'U': s += "uint"; break;
|
|
|
|
case 'B': s += "bool"; break;
|
|
|
|
case 'S': s += "sampler"; break;
|
|
|
|
case 's': s += "SamplerComparisonState"; break;
|
2016-10-04 16:58:14 -06:00
|
|
|
case 'T': s += ((isBuffer && isImage) ? "RWBuffer" :
|
2017-01-06 00:34:48 -07:00
|
|
|
isBuffer ? "Buffer" :
|
2016-11-15 10:11:04 -07:00
|
|
|
isImage ? "RWTexture" : "Texture"); break;
|
|
|
|
case 'i': s += ((isBuffer && isImage) ? "RWBuffer" :
|
2017-01-06 00:34:48 -07:00
|
|
|
isBuffer ? "Buffer" :
|
2016-11-15 10:11:04 -07:00
|
|
|
isImage ? "RWTexture" : "Texture"); break;
|
|
|
|
case 'u': s += ((isBuffer && isImage) ? "RWBuffer" :
|
|
|
|
isBuffer ? "Buffer" :
|
|
|
|
isImage ? "RWTexture" : "Texture"); break;
|
|
|
|
default: s += "UNKNOWN_TYPE"; break;
|
2016-06-20 13:26:59 -06:00
|
|
|
}
|
|
|
|
} else {
|
2016-07-12 14:45:05 -06:00
|
|
|
switch (type) {
|
2016-06-20 13:26:59 -06:00
|
|
|
case '-': s += "void"; break;
|
2016-07-27 15:46:48 -06:00
|
|
|
case 'F': s += BaseTypeName(order, "float", "vec", "mat"); break;
|
|
|
|
case 'D': s += BaseTypeName(order, "double", "dvec", "dmat"); break;
|
|
|
|
case 'I': s += BaseTypeName(order, "int", "ivec", "imat"); break;
|
|
|
|
case 'U': s += BaseTypeName(order, "uint", "uvec", "umat"); break;
|
|
|
|
case 'B': s += BaseTypeName(order, "bool", "bvec", "bmat"); break;
|
|
|
|
case 'S': s += "sampler"; break;
|
|
|
|
case 's': s += "samplerShadow"; break;
|
2016-07-12 14:45:05 -06:00
|
|
|
case 'T': // fall through
|
|
|
|
case 'i': // ...
|
|
|
|
case 'u': // ...
|
2016-07-27 15:46:48 -06:00
|
|
|
if (type != 'T') // create itexture, utexture, etc
|
2016-07-12 14:45:05 -06:00
|
|
|
s += type;
|
|
|
|
|
2016-10-04 16:58:14 -06:00
|
|
|
s += ((isImage && isBuffer) ? "imageBuffer" :
|
|
|
|
isImage ? "image" :
|
|
|
|
isBuffer ? "samplerBuffer" :
|
|
|
|
"texture");
|
2016-07-12 14:45:05 -06:00
|
|
|
break;
|
|
|
|
|
2016-06-20 13:26:59 -06:00
|
|
|
default: s += "UNKNOWN_TYPE"; break;
|
|
|
|
}
|
2016-05-26 10:10:16 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// handle fixed vector sizes, such as float3, and only ever 3.
|
2016-07-26 15:19:28 -06:00
|
|
|
const int fixedVecSize = FixedVecSize(argOrder);
|
2016-05-26 10:10:16 -06:00
|
|
|
if (fixedVecSize != 0)
|
|
|
|
dim0 = dim1 = fixedVecSize;
|
|
|
|
|
|
|
|
// Add sampler dimensions
|
2016-07-22 08:28:11 -06:00
|
|
|
if (isSampler || isTexture) {
|
2016-07-27 15:46:48 -06:00
|
|
|
if ((order == 'V' || isTexture) && !isBuffer) {
|
2016-06-29 10:58:58 -06:00
|
|
|
switch (dim0) {
|
2016-07-26 15:19:28 -06:00
|
|
|
case 1: s += "1D"; break;
|
|
|
|
case 2: s += (isMS ? "2DMS" : "2D"); break;
|
|
|
|
case 3: s += "3D"; break;
|
|
|
|
case 4: s += "Cube"; break;
|
|
|
|
default: s += "UNKNOWN_SAMPLER"; break;
|
2016-06-29 10:58:58 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Non-sampler type:
|
|
|
|
// verify dimensions
|
2016-07-12 14:45:05 -06:00
|
|
|
if (((order == 'V' || order == 'M') && (dim0 < 1 || dim0 > 4)) ||
|
|
|
|
(order == 'M' && (dim1 < 1 || dim1 > 4))) {
|
2016-06-29 10:58:58 -06:00
|
|
|
s += "UNKNOWN_DIMENSION";
|
|
|
|
return s;
|
2016-05-26 10:10:16 -06:00
|
|
|
}
|
|
|
|
|
2016-07-12 14:45:05 -06:00
|
|
|
switch (order) {
|
2016-06-29 10:58:58 -06:00
|
|
|
case '-': break; // no dimensions for voids
|
|
|
|
case 'S': break; // no dimensions on scalars
|
2016-08-24 14:36:13 -06:00
|
|
|
case 'V':
|
|
|
|
s += ('0' + char(dim0));
|
|
|
|
break;
|
2017-01-06 00:34:48 -07:00
|
|
|
case 'M':
|
2016-08-24 14:36:13 -06:00
|
|
|
s += ('0' + char(dim0));
|
|
|
|
s += 'x';
|
|
|
|
s += ('0' + char(dim1));
|
|
|
|
break;
|
2016-07-26 15:19:28 -06:00
|
|
|
default:
|
|
|
|
break;
|
2016-06-20 13:26:59 -06:00
|
|
|
}
|
2016-05-26 10:10:16 -06:00
|
|
|
}
|
|
|
|
|
2016-07-12 14:45:05 -06:00
|
|
|
// handle arrayed textures
|
|
|
|
if (isArrayed)
|
|
|
|
s += "Array";
|
|
|
|
|
2016-11-15 10:11:04 -07:00
|
|
|
// For HLSL, append return type for texture types
|
|
|
|
if (UseHlslTypes) {
|
|
|
|
switch (type) {
|
|
|
|
case 'i': s += "<int4>"; break;
|
|
|
|
case 'u': s += "<uint4>"; break;
|
|
|
|
case 'T': s += "<float4>"; break;
|
|
|
|
default: break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-26 10:10:16 -06:00
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2016-11-15 10:11:04 -07:00
|
|
|
// The GLSL parser can be used to parse a subset of HLSL prototypes. However, many valid HLSL prototypes
|
2016-05-26 10:10:16 -06:00
|
|
|
// are not valid GLSL prototypes. This rejects the invalid ones. Thus, there is a single switch below
|
|
|
|
// to enable creation of the entire HLSL space.
|
2016-11-15 10:11:04 -07:00
|
|
|
inline bool IsValid(const char* cname, char retOrder, char retType, char argOrder, char argType, int dim0, int dim1)
|
2016-05-26 10:10:16 -06:00
|
|
|
{
|
2016-11-15 10:11:04 -07:00
|
|
|
const bool isVec = (argOrder == 'V');
|
|
|
|
const bool isMat = (argOrder == 'M');
|
2016-05-26 10:10:16 -06:00
|
|
|
|
2016-11-15 10:11:04 -07:00
|
|
|
const std::string name(cname);
|
2016-06-29 10:58:58 -06:00
|
|
|
|
2016-11-15 10:11:04 -07:00
|
|
|
// these do not have vec1 versions
|
|
|
|
if (dim0 == 1 && (name == "length" || name == "normalize" || name == "reflect" || name == "refract"))
|
2016-05-26 10:10:16 -06:00
|
|
|
return false;
|
|
|
|
|
2016-11-15 10:11:04 -07:00
|
|
|
if (!IsTextureType(argOrder) && (isVec && dim0 == 1)) // avoid vec1
|
2016-05-26 10:10:16 -06:00
|
|
|
return false;
|
|
|
|
|
2016-11-15 10:11:04 -07:00
|
|
|
if (UseHlslTypes) {
|
|
|
|
// NO further restrictions for HLSL
|
|
|
|
} else {
|
|
|
|
// GLSL parser restrictions
|
|
|
|
if ((isMat && (argType == 'I' || argType == 'U' || argType == 'B')) ||
|
|
|
|
(retOrder == 'M' && (retType == 'I' || retType == 'U' || retType == 'B')))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (isMat && dim0 == 1 && dim1 == 1) // avoid mat1x1
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (isMat && dim1 == 1) // TODO: avoid mat Nx1 until we find the right GLSL profile
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (name == "GetRenderTargetSamplePosition" ||
|
|
|
|
name == "tex1D" ||
|
|
|
|
name == "tex1Dgrad")
|
|
|
|
return false;
|
|
|
|
}
|
2016-05-26 10:10:16 -06:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// return position of end of argument specifier
|
|
|
|
inline const char* FindEndOfArg(const char* arg)
|
|
|
|
{
|
|
|
|
while (!IsEndOfArg(arg))
|
|
|
|
++arg;
|
|
|
|
|
|
|
|
return *arg == '\0' ? nullptr : arg;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return pointer to beginning of Nth argument specifier in the string.
|
|
|
|
inline const char* NthArg(const char* arg, int n)
|
|
|
|
{
|
|
|
|
for (int x=0; x<n && arg; ++x)
|
|
|
|
if ((arg = FindEndOfArg(arg)) != nullptr)
|
|
|
|
++arg; // skip arg separator
|
|
|
|
|
|
|
|
return arg;
|
|
|
|
}
|
|
|
|
|
2016-07-08 22:09:10 -06:00
|
|
|
inline void FindVectorMatrixBounds(const char* argOrder, int fixedVecSize, int& dim0Min, int& dim0Max, int& /*dim1Min*/, int& dim1Max)
|
2016-05-26 10:10:16 -06:00
|
|
|
{
|
|
|
|
for (int arg = 0; ; ++arg) {
|
|
|
|
const char* nthArgOrder(NthArg(argOrder, arg));
|
|
|
|
if (nthArgOrder == nullptr)
|
|
|
|
break;
|
|
|
|
else if (*nthArgOrder == 'V')
|
|
|
|
dim0Max = 4;
|
|
|
|
else if (*nthArgOrder == 'M')
|
|
|
|
dim0Max = dim1Max = 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fixedVecSize > 0) // handle fixed sized vectors
|
|
|
|
dim0Min = dim0Max = fixedVecSize;
|
|
|
|
}
|
2017-01-06 00:34:48 -07:00
|
|
|
|
2016-05-26 10:10:16 -06:00
|
|
|
} // end anonymous namespace
|
2016-05-20 13:45:20 -06:00
|
|
|
|
|
|
|
namespace glslang {
|
|
|
|
|
|
|
|
TBuiltInParseablesHlsl::TBuiltInParseablesHlsl()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2016-06-20 13:26:59 -06:00
|
|
|
//
|
|
|
|
// Handle creation of mat*mat specially, since it doesn't fall conveniently out of
|
|
|
|
// the generic prototype creation code below.
|
|
|
|
//
|
|
|
|
void TBuiltInParseablesHlsl::createMatTimesMat()
|
|
|
|
{
|
|
|
|
TString& s = commonBuiltins;
|
|
|
|
|
|
|
|
const int first = (UseHlslTypes ? 1 : 2);
|
|
|
|
|
|
|
|
for (int xRows = first; xRows <=4; xRows++) {
|
|
|
|
for (int xCols = first; xCols <=4; xCols++) {
|
|
|
|
const int yRows = xCols;
|
|
|
|
for (int yCols = first; yCols <=4; yCols++) {
|
|
|
|
const int retRows = xRows;
|
|
|
|
const int retCols = yCols;
|
|
|
|
|
2016-08-24 14:36:13 -06:00
|
|
|
// Create a mat * mat of the appropriate dimensions
|
2016-06-20 13:26:59 -06:00
|
|
|
AppendTypeName(s, "M", "F", retRows, retCols); // add return type
|
|
|
|
s.append(" "); // space between type and name
|
|
|
|
s.append("mul"); // intrinsic name
|
|
|
|
s.append("("); // open paren
|
|
|
|
|
|
|
|
AppendTypeName(s, "M", "F", xRows, xCols); // add X input
|
|
|
|
s.append(", ");
|
|
|
|
AppendTypeName(s, "M", "F", yRows, yCols); // add Y input
|
|
|
|
|
|
|
|
s.append(");\n"); // close paren
|
|
|
|
}
|
2016-08-24 14:36:13 -06:00
|
|
|
|
|
|
|
// Create M*V
|
|
|
|
AppendTypeName(s, "V", "F", xRows, 1); // add return type
|
|
|
|
s.append(" "); // space between type and name
|
|
|
|
s.append("mul"); // intrinsic name
|
|
|
|
s.append("("); // open paren
|
|
|
|
|
|
|
|
AppendTypeName(s, "M", "F", xRows, xCols); // add X input
|
|
|
|
s.append(", ");
|
|
|
|
AppendTypeName(s, "V", "F", xCols, 1); // add Y input
|
|
|
|
|
|
|
|
s.append(");\n"); // close paren
|
|
|
|
|
|
|
|
// Create V*M
|
|
|
|
AppendTypeName(s, "V", "F", xCols, 1); // add return type
|
|
|
|
s.append(" "); // space between type and name
|
|
|
|
s.append("mul"); // intrinsic name
|
|
|
|
s.append("("); // open paren
|
|
|
|
|
|
|
|
AppendTypeName(s, "V", "F", xRows, 1); // add Y input
|
|
|
|
s.append(", ");
|
|
|
|
AppendTypeName(s, "M", "F", xRows, xCols); // add X input
|
|
|
|
|
|
|
|
s.append(");\n"); // close paren
|
2016-06-20 13:26:59 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-20 13:45:20 -06:00
|
|
|
//
|
|
|
|
// Add all context-independent built-in functions and variables that are present
|
|
|
|
// for the given version and profile. Share common ones across stages, otherwise
|
|
|
|
// make stage-specific entries.
|
|
|
|
//
|
|
|
|
// Most built-ins variables can be added as simple text strings. Some need to
|
|
|
|
// be added programmatically, which is done later in IdentifyBuiltIns() below.
|
|
|
|
//
|
2016-07-08 22:09:10 -06:00
|
|
|
void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, const SpvVersion& /*spvVersion*/)
|
2016-05-20 13:45:20 -06:00
|
|
|
{
|
2016-07-22 08:28:11 -06:00
|
|
|
static const EShLanguageMask EShLangAll = EShLanguageMask(EShLangCount - 1);
|
2016-08-11 07:29:30 -06:00
|
|
|
|
|
|
|
// These are the actual stage masks defined in the documentation, in case they are
|
|
|
|
// needed for furture validation. For now, they are commented out, and set below
|
|
|
|
// to EShLangAll, to allow any intrinsic to be used in any shader, which is legal
|
|
|
|
// if it is not called.
|
2017-01-06 00:34:48 -07:00
|
|
|
//
|
2016-08-11 07:29:30 -06:00
|
|
|
// static const EShLanguageMask EShLangPSCS = EShLanguageMask(EShLangFragmentMask | EShLangComputeMask);
|
|
|
|
// static const EShLanguageMask EShLangVSPSGS = EShLanguageMask(EShLangVertexMask | EShLangFragmentMask | EShLangGeometryMask);
|
|
|
|
// static const EShLanguageMask EShLangCS = EShLangComputeMask;
|
|
|
|
// static const EShLanguageMask EShLangPS = EShLangFragmentMask;
|
|
|
|
// static const EShLanguageMask EShLangHS = EShLangTessControlMask;
|
|
|
|
|
|
|
|
// This set uses EShLangAll for everything.
|
|
|
|
static const EShLanguageMask EShLangPSCS = EShLangAll;
|
|
|
|
static const EShLanguageMask EShLangVSPSGS = EShLangAll;
|
|
|
|
static const EShLanguageMask EShLangCS = EShLangAll;
|
|
|
|
static const EShLanguageMask EShLangPS = EShLangAll;
|
|
|
|
static const EShLanguageMask EShLangHS = EShLangAll;
|
2016-11-17 15:04:20 -07:00
|
|
|
static const EShLanguageMask EShLangGS = EShLangAll;
|
2016-05-26 10:10:16 -06:00
|
|
|
|
|
|
|
// This structure encodes the prototype information for each HLSL intrinsic.
|
|
|
|
// Because explicit enumeration would be cumbersome, it's procedurally generated.
|
|
|
|
// orderKey can be:
|
|
|
|
// S = scalar, V = vector, M = matrix, - = void
|
|
|
|
// typekey can be:
|
2016-07-19 14:28:05 -06:00
|
|
|
// D = double, F = float, U = uint, I = int, B = bool, S = sampler, s = shadowSampler
|
2016-05-26 10:10:16 -06:00
|
|
|
// An empty order or type key repeats the first one. E.g: SVM,, means 3 args each of SVM.
|
2016-06-16 20:59:42 -06:00
|
|
|
// '>' as first letter of order creates an output parameter
|
|
|
|
// '<' as first letter of order creates an input parameter
|
2016-05-26 10:10:16 -06:00
|
|
|
// '^' as first letter of order takes transpose dimensions
|
2016-07-12 14:45:05 -06:00
|
|
|
// '%' as first letter of order creates texture of given F/I/U type (texture, itexture, etc)
|
|
|
|
// '@' as first letter of order creates arrayed texture of given type
|
2016-07-26 15:19:28 -06:00
|
|
|
// '$' / '&' as first letter of order creates 2DMS / 2DMSArray textures
|
2016-07-27 15:46:48 -06:00
|
|
|
// '*' as first letter of order creates buffer object
|
2016-10-04 16:58:14 -06:00
|
|
|
// '!' as first letter of order creates image object
|
|
|
|
// '#' as first letter of order creates arrayed image object
|
|
|
|
// '~' as first letter of order creates an image buffer object
|
2016-05-26 10:10:16 -06:00
|
|
|
|
|
|
|
static const struct {
|
|
|
|
const char* name; // intrinsic name
|
|
|
|
const char* retOrder; // return type key: empty matches order of 1st argument
|
|
|
|
const char* retType; // return type key: empty matches type of 1st argument
|
|
|
|
const char* argOrder; // argument order key
|
|
|
|
const char* argType; // argument type key
|
|
|
|
unsigned int stage; // stage mask
|
|
|
|
} hlslIntrinsics[] = {
|
2016-07-22 08:28:11 -06:00
|
|
|
// name retOrd retType argOrder argType stage mask
|
2016-05-26 10:10:16 -06:00
|
|
|
// -----------------------------------------------------------------------------------------------
|
2016-07-22 08:28:11 -06:00
|
|
|
{ "abort", nullptr, nullptr, "-", "-", EShLangAll },
|
|
|
|
{ "abs", nullptr, nullptr, "SVM", "DFUI", EShLangAll },
|
|
|
|
{ "acos", nullptr, nullptr, "SVM", "F", EShLangAll },
|
2016-11-15 10:11:04 -07:00
|
|
|
{ "all", "S", "B", "SVM", "BFIU", EShLangAll },
|
2016-08-11 07:29:30 -06:00
|
|
|
{ "AllMemoryBarrier", nullptr, nullptr, "-", "-", EShLangCS },
|
|
|
|
{ "AllMemoryBarrierWithGroupSync", nullptr, nullptr, "-", "-", EShLangCS },
|
2016-11-15 10:11:04 -07:00
|
|
|
{ "any", "S", "B", "SVM", "BFIU", EShLangAll },
|
HLSL: add intrinsic function implicit promotions
This PR handles implicit promotions for intrinsics when there is no exact match,
such as for example clamp(int, bool, float). In this case the int and bool will
be promoted to a float, and the clamp(float, float, float) form used.
These promotions can be mixed with shape conversions, e.g, clamp(int, bool2, float2).
Output conversions are handled either via the existing addOutputArgumentConversion
function, which this PR generalizes to handle either aggregates or unaries, or by
intrinsic decomposition. If there are methods or intrinsics to be decomposed,
then decomposition is responsible for any output conversions, which turns out to
happen automatically in all current cases. This can be revisited once inout
conversions are in place.
Some cases of actual ambiguity were fixed in several tests, e.g, spv.register.autoassign.*
Some intrinsics with only uint versions were expanded to signed ints natively, where the
underlying AST and SPIR-V supports that. E.g, countbits. This avoids extraneous
conversion nodes.
A new function promoteAggregate is added, and used by findFunction. This is essentially
a generalization of the "promote 1st or 2nd arg" algorithm in promoteBinary.
The actual selection proceeds in three steps, as described in the comments in
hlslParseContext::findFunction:
1. Attempt an exact match. If found, use it.
2. If not, obtain the operator from step 1, and promote arguments.
3. Re-select the intrinsic overload from the results of step 2.
2016-11-02 12:42:34 -06:00
|
|
|
{ "asdouble", "S", "D", "S,", "UI,", EShLangAll },
|
|
|
|
{ "asdouble", "V2", "D", "V2,", "UI,", EShLangAll },
|
2016-07-22 08:28:11 -06:00
|
|
|
{ "asfloat", nullptr, "F", "SVM", "BFIU", EShLangAll },
|
|
|
|
{ "asin", nullptr, nullptr, "SVM", "F", EShLangAll },
|
|
|
|
{ "asint", nullptr, "I", "SVM", "FU", EShLangAll },
|
|
|
|
{ "asuint", nullptr, "U", "SVM", "FU", EShLangAll },
|
|
|
|
{ "atan", nullptr, nullptr, "SVM", "F", EShLangAll },
|
|
|
|
{ "atan2", nullptr, nullptr, "SVM,", "F,", EShLangAll },
|
|
|
|
{ "ceil", nullptr, nullptr, "SVM", "F", EShLangAll },
|
|
|
|
{ "CheckAccessFullyMapped", "S", "B" , "S", "U", EShLangPSCS },
|
|
|
|
{ "clamp", nullptr, nullptr, "SVM,,", "FUI,,", EShLangAll },
|
2016-08-11 07:29:30 -06:00
|
|
|
{ "clip", "-", "-", "SVM", "F", EShLangPS },
|
2016-07-22 08:28:11 -06:00
|
|
|
{ "cos", nullptr, nullptr, "SVM", "F", EShLangAll },
|
|
|
|
{ "cosh", nullptr, nullptr, "SVM", "F", EShLangAll },
|
HLSL: add intrinsic function implicit promotions
This PR handles implicit promotions for intrinsics when there is no exact match,
such as for example clamp(int, bool, float). In this case the int and bool will
be promoted to a float, and the clamp(float, float, float) form used.
These promotions can be mixed with shape conversions, e.g, clamp(int, bool2, float2).
Output conversions are handled either via the existing addOutputArgumentConversion
function, which this PR generalizes to handle either aggregates or unaries, or by
intrinsic decomposition. If there are methods or intrinsics to be decomposed,
then decomposition is responsible for any output conversions, which turns out to
happen automatically in all current cases. This can be revisited once inout
conversions are in place.
Some cases of actual ambiguity were fixed in several tests, e.g, spv.register.autoassign.*
Some intrinsics with only uint versions were expanded to signed ints natively, where the
underlying AST and SPIR-V supports that. E.g, countbits. This avoids extraneous
conversion nodes.
A new function promoteAggregate is added, and used by findFunction. This is essentially
a generalization of the "promote 1st or 2nd arg" algorithm in promoteBinary.
The actual selection proceeds in three steps, as described in the comments in
hlslParseContext::findFunction:
1. Attempt an exact match. If found, use it.
2. If not, obtain the operator from step 1, and promote arguments.
3. Re-select the intrinsic overload from the results of step 2.
2016-11-02 12:42:34 -06:00
|
|
|
{ "countbits", nullptr, nullptr, "SV", "UI", EShLangAll },
|
2016-07-22 08:28:11 -06:00
|
|
|
{ "cross", nullptr, nullptr, "V3,", "F,", EShLangAll },
|
|
|
|
{ "D3DCOLORtoUBYTE4", "V4", "I", "V4", "F", EShLangAll },
|
2016-08-11 07:29:30 -06:00
|
|
|
{ "ddx", nullptr, nullptr, "SVM", "F", EShLangPS },
|
|
|
|
{ "ddx_coarse", nullptr, nullptr, "SVM", "F", EShLangPS },
|
|
|
|
{ "ddx_fine", nullptr, nullptr, "SVM", "F", EShLangPS },
|
|
|
|
{ "ddy", nullptr, nullptr, "SVM", "F", EShLangPS },
|
|
|
|
{ "ddy_coarse", nullptr, nullptr, "SVM", "F", EShLangPS },
|
|
|
|
{ "ddy_fine", nullptr, nullptr, "SVM", "F", EShLangPS },
|
2016-07-22 08:28:11 -06:00
|
|
|
{ "degrees", nullptr, nullptr, "SVM", "F", EShLangAll },
|
|
|
|
{ "determinant", "S", "F", "M", "F", EShLangAll },
|
|
|
|
{ "DeviceMemoryBarrier", nullptr, nullptr, "-", "-", EShLangPSCS },
|
2016-08-11 07:29:30 -06:00
|
|
|
{ "DeviceMemoryBarrierWithGroupSync", nullptr, nullptr, "-", "-", EShLangCS },
|
2016-07-22 08:28:11 -06:00
|
|
|
{ "distance", "S", "F", "V,", "F,", EShLangAll },
|
2016-12-23 18:56:57 -07:00
|
|
|
{ "dot", "S", nullptr, "SV,", "FI,", EShLangAll },
|
2016-07-22 08:28:11 -06:00
|
|
|
{ "dst", nullptr, nullptr, "V4,", "F,", EShLangAll },
|
|
|
|
// { "errorf", "-", "-", "", "", EShLangAll }, TODO: varargs
|
2016-08-11 07:29:30 -06:00
|
|
|
{ "EvaluateAttributeAtCentroid", nullptr, nullptr, "SVM", "F", EShLangPS },
|
|
|
|
{ "EvaluateAttributeAtSample", nullptr, nullptr, "SVM,S", "F,U", EShLangPS },
|
|
|
|
{ "EvaluateAttributeSnapped", nullptr, nullptr, "SVM,V2", "F,I", EShLangPS },
|
2016-07-22 08:28:11 -06:00
|
|
|
{ "exp", nullptr, nullptr, "SVM", "F", EShLangAll },
|
|
|
|
{ "exp2", nullptr, nullptr, "SVM", "F", EShLangAll },
|
|
|
|
{ "f16tof32", nullptr, "F", "SV", "U", EShLangAll },
|
|
|
|
{ "f32tof16", nullptr, "U", "SV", "F", EShLangAll },
|
|
|
|
{ "faceforward", nullptr, nullptr, "V,,", "F,,", EShLangAll },
|
|
|
|
{ "firstbithigh", nullptr, nullptr, "SV", "UI", EShLangAll },
|
|
|
|
{ "firstbitlow", nullptr, nullptr, "SV", "UI", EShLangAll },
|
|
|
|
{ "floor", nullptr, nullptr, "SVM", "F", EShLangAll },
|
|
|
|
{ "fma", nullptr, nullptr, "SVM,,", "D,,", EShLangAll },
|
|
|
|
{ "fmod", nullptr, nullptr, "SVM,", "F,", EShLangAll },
|
|
|
|
{ "frac", nullptr, nullptr, "SVM", "F", EShLangAll },
|
|
|
|
{ "frexp", nullptr, nullptr, "SVM,", "F,", EShLangAll },
|
2016-08-11 07:29:30 -06:00
|
|
|
{ "fwidth", nullptr, nullptr, "SVM", "F", EShLangPS },
|
2016-07-22 08:28:11 -06:00
|
|
|
{ "GetRenderTargetSampleCount", "S", "U", "-", "-", EShLangAll },
|
|
|
|
{ "GetRenderTargetSamplePosition", "V2", "F", "V1", "I", EShLangAll },
|
2016-08-11 07:29:30 -06:00
|
|
|
{ "GroupMemoryBarrier", nullptr, nullptr, "-", "-", EShLangCS },
|
|
|
|
{ "GroupMemoryBarrierWithGroupSync", nullptr, nullptr, "-", "-", EShLangCS },
|
2016-07-22 08:28:11 -06:00
|
|
|
{ "InterlockedAdd", "-", "-", "SVM,,>", "UI,,", EShLangPSCS },
|
|
|
|
{ "InterlockedAdd", "-", "-", "SVM,", "UI,", EShLangPSCS },
|
|
|
|
{ "InterlockedAnd", "-", "-", "SVM,,>", "UI,,", EShLangPSCS },
|
|
|
|
{ "InterlockedAnd", "-", "-", "SVM,", "UI,", EShLangPSCS },
|
|
|
|
{ "InterlockedCompareExchange", "-", "-", "SVM,,,>", "UI,,,", EShLangPSCS },
|
|
|
|
{ "InterlockedCompareStore", "-", "-", "SVM,,", "UI,,", EShLangPSCS },
|
|
|
|
{ "InterlockedExchange", "-", "-", "SVM,,>", "UI,,", EShLangPSCS },
|
|
|
|
{ "InterlockedMax", "-", "-", "SVM,,>", "UI,,", EShLangPSCS },
|
|
|
|
{ "InterlockedMax", "-", "-", "SVM,", "UI,", EShLangPSCS },
|
|
|
|
{ "InterlockedMin", "-", "-", "SVM,,>", "UI,,", EShLangPSCS },
|
|
|
|
{ "InterlockedMin", "-", "-", "SVM,", "UI,", EShLangPSCS },
|
|
|
|
{ "InterlockedOr", "-", "-", "SVM,,>", "UI,,", EShLangPSCS },
|
|
|
|
{ "InterlockedOr", "-", "-", "SVM,", "UI,", EShLangPSCS },
|
|
|
|
{ "InterlockedXor", "-", "-", "SVM,,>", "UI,,", EShLangPSCS },
|
|
|
|
{ "InterlockedXor", "-", "-", "SVM,", "UI,", EShLangPSCS },
|
|
|
|
{ "isfinite", nullptr, "B" , "SVM", "F", EShLangAll },
|
|
|
|
{ "isinf", nullptr, "B" , "SVM", "F", EShLangAll },
|
|
|
|
{ "isnan", nullptr, "B" , "SVM", "F", EShLangAll },
|
|
|
|
{ "ldexp", nullptr, nullptr, "SVM,", "F,", EShLangAll },
|
|
|
|
{ "length", "S", "F", "V", "F", EShLangAll },
|
2016-07-28 13:20:57 -06:00
|
|
|
{ "lerp", nullptr, nullptr, "VM,,", "F,,", EShLangAll },
|
|
|
|
{ "lerp", nullptr, nullptr, "SVM,,S", "F,,", EShLangAll },
|
2016-07-22 08:28:11 -06:00
|
|
|
{ "lit", "V4", "F", "S,,", "F,,", EShLangAll },
|
|
|
|
{ "log", nullptr, nullptr, "SVM", "F", EShLangAll },
|
|
|
|
{ "log10", nullptr, nullptr, "SVM", "F", EShLangAll },
|
|
|
|
{ "log2", nullptr, nullptr, "SVM", "F", EShLangAll },
|
|
|
|
{ "mad", nullptr, nullptr, "SVM,,", "DFUI,,", EShLangAll },
|
HLSL: add intrinsic function implicit promotions
This PR handles implicit promotions for intrinsics when there is no exact match,
such as for example clamp(int, bool, float). In this case the int and bool will
be promoted to a float, and the clamp(float, float, float) form used.
These promotions can be mixed with shape conversions, e.g, clamp(int, bool2, float2).
Output conversions are handled either via the existing addOutputArgumentConversion
function, which this PR generalizes to handle either aggregates or unaries, or by
intrinsic decomposition. If there are methods or intrinsics to be decomposed,
then decomposition is responsible for any output conversions, which turns out to
happen automatically in all current cases. This can be revisited once inout
conversions are in place.
Some cases of actual ambiguity were fixed in several tests, e.g, spv.register.autoassign.*
Some intrinsics with only uint versions were expanded to signed ints natively, where the
underlying AST and SPIR-V supports that. E.g, countbits. This avoids extraneous
conversion nodes.
A new function promoteAggregate is added, and used by findFunction. This is essentially
a generalization of the "promote 1st or 2nd arg" algorithm in promoteBinary.
The actual selection proceeds in three steps, as described in the comments in
hlslParseContext::findFunction:
1. Attempt an exact match. If found, use it.
2. If not, obtain the operator from step 1, and promote arguments.
3. Re-select the intrinsic overload from the results of step 2.
2016-11-02 12:42:34 -06:00
|
|
|
{ "max", nullptr, nullptr, "SVM,", "FIU,", EShLangAll },
|
|
|
|
{ "min", nullptr, nullptr, "SVM,", "FIU,", EShLangAll },
|
|
|
|
{ "modf", nullptr, nullptr, "SVM,>", "FIU,", EShLangAll },
|
2016-07-22 08:28:11 -06:00
|
|
|
{ "msad4", "V4", "U", "S,V2,V4", "U,,", EShLangAll },
|
|
|
|
{ "mul", "S", nullptr, "S,S", "FI,", EShLangAll },
|
|
|
|
{ "mul", "V", nullptr, "S,V", "FI,", EShLangAll },
|
|
|
|
{ "mul", "M", nullptr, "S,M", "FI,", EShLangAll },
|
|
|
|
{ "mul", "V", nullptr, "V,S", "FI,", EShLangAll },
|
|
|
|
{ "mul", "S", nullptr, "V,V", "FI,", EShLangAll },
|
|
|
|
{ "mul", "M", nullptr, "M,S", "FI,", EShLangAll },
|
2016-06-20 13:26:59 -06:00
|
|
|
// mat*mat form of mul is handled in createMatTimesMat()
|
2016-08-11 07:29:30 -06:00
|
|
|
{ "noise", "S", "F", "V", "F", EShLangPS },
|
2016-07-22 08:28:11 -06:00
|
|
|
{ "normalize", nullptr, nullptr, "V", "F", EShLangAll },
|
|
|
|
{ "pow", nullptr, nullptr, "SVM,", "F,", EShLangAll },
|
|
|
|
// { "printf", "-", "-", "", "", EShLangAll }, TODO: varargs
|
2016-08-11 07:29:30 -06:00
|
|
|
{ "Process2DQuadTessFactorsAvg", "-", "-", "V4,V2,>V4,>V2,", "F,,,,", EShLangHS },
|
|
|
|
{ "Process2DQuadTessFactorsMax", "-", "-", "V4,V2,>V4,>V2,", "F,,,,", EShLangHS },
|
|
|
|
{ "Process2DQuadTessFactorsMin", "-", "-", "V4,V2,>V4,>V2,", "F,,,,", EShLangHS },
|
|
|
|
{ "ProcessIsolineTessFactors", "-", "-", "S,,>,>", "F,,,", EShLangHS },
|
|
|
|
{ "ProcessQuadTessFactorsAvg", "-", "-", "V4,S,>V4,>V2,", "F,,,,", EShLangHS },
|
|
|
|
{ "ProcessQuadTessFactorsMax", "-", "-", "V4,S,>V4,>V2,", "F,,,,", EShLangHS },
|
|
|
|
{ "ProcessQuadTessFactorsMin", "-", "-", "V4,S,>V4,>V2,", "F,,,,", EShLangHS },
|
|
|
|
{ "ProcessTriTessFactorsAvg", "-", "-", "V3,S,>V3,>S,", "F,,,,", EShLangHS },
|
|
|
|
{ "ProcessTriTessFactorsMax", "-", "-", "V3,S,>V3,>S,", "F,,,,", EShLangHS },
|
|
|
|
{ "ProcessTriTessFactorsMin", "-", "-", "V3,S,>V3,>S,", "F,,,,", EShLangHS },
|
2016-07-22 08:28:11 -06:00
|
|
|
{ "radians", nullptr, nullptr, "SVM", "F", EShLangAll },
|
|
|
|
{ "rcp", nullptr, nullptr, "SVM", "FD", EShLangAll },
|
|
|
|
{ "reflect", nullptr, nullptr, "V,", "F,", EShLangAll },
|
|
|
|
{ "refract", nullptr, nullptr, "V,V,S", "F,,", EShLangAll },
|
HLSL: add intrinsic function implicit promotions
This PR handles implicit promotions for intrinsics when there is no exact match,
such as for example clamp(int, bool, float). In this case the int and bool will
be promoted to a float, and the clamp(float, float, float) form used.
These promotions can be mixed with shape conversions, e.g, clamp(int, bool2, float2).
Output conversions are handled either via the existing addOutputArgumentConversion
function, which this PR generalizes to handle either aggregates or unaries, or by
intrinsic decomposition. If there are methods or intrinsics to be decomposed,
then decomposition is responsible for any output conversions, which turns out to
happen automatically in all current cases. This can be revisited once inout
conversions are in place.
Some cases of actual ambiguity were fixed in several tests, e.g, spv.register.autoassign.*
Some intrinsics with only uint versions were expanded to signed ints natively, where the
underlying AST and SPIR-V supports that. E.g, countbits. This avoids extraneous
conversion nodes.
A new function promoteAggregate is added, and used by findFunction. This is essentially
a generalization of the "promote 1st or 2nd arg" algorithm in promoteBinary.
The actual selection proceeds in three steps, as described in the comments in
hlslParseContext::findFunction:
1. Attempt an exact match. If found, use it.
2. If not, obtain the operator from step 1, and promote arguments.
3. Re-select the intrinsic overload from the results of step 2.
2016-11-02 12:42:34 -06:00
|
|
|
{ "reversebits", nullptr, nullptr, "SV", "UI", EShLangAll },
|
2016-07-22 08:28:11 -06:00
|
|
|
{ "round", nullptr, nullptr, "SVM", "F", EShLangAll },
|
|
|
|
{ "rsqrt", nullptr, nullptr, "SVM", "F", EShLangAll },
|
|
|
|
{ "saturate", nullptr, nullptr , "SVM", "F", EShLangAll },
|
|
|
|
{ "sign", nullptr, nullptr, "SVM", "FI", EShLangAll },
|
|
|
|
{ "sin", nullptr, nullptr, "SVM", "F", EShLangAll },
|
|
|
|
{ "sincos", "-", "-", "SVM,>,>", "F,,", EShLangAll },
|
|
|
|
{ "sinh", nullptr, nullptr, "SVM", "F", EShLangAll },
|
|
|
|
{ "smoothstep", nullptr, nullptr, "SVM,,", "F,,", EShLangAll },
|
|
|
|
{ "sqrt", nullptr, nullptr, "SVM", "F", EShLangAll },
|
|
|
|
{ "step", nullptr, nullptr, "SVM,", "F,", EShLangAll },
|
|
|
|
{ "tan", nullptr, nullptr, "SVM", "F", EShLangAll },
|
|
|
|
{ "tanh", nullptr, nullptr, "SVM", "F", EShLangAll },
|
2016-08-11 07:29:30 -06:00
|
|
|
{ "tex1D", "V4", "F", "V1,S", "S,F", EShLangPS },
|
|
|
|
{ "tex1D", "V4", "F", "V1,S,V1,", "S,F,,", EShLangPS },
|
|
|
|
{ "tex1Dbias", "V4", "F", "V1,V4", "S,F", EShLangPS },
|
|
|
|
{ "tex1Dgrad", "V4", "F", "V1,,,", "S,F,,", EShLangPS },
|
|
|
|
{ "tex1Dlod", "V4", "F", "V1,V4", "S,F", EShLangPS },
|
|
|
|
{ "tex1Dproj", "V4", "F", "V1,V4", "S,F", EShLangPS },
|
|
|
|
{ "tex2D", "V4", "F", "V2,", "S,F", EShLangPS },
|
|
|
|
{ "tex2D", "V4", "F", "V2,,,", "S,F,,", EShLangPS },
|
|
|
|
{ "tex2Dbias", "V4", "F", "V2,V4", "S,F", EShLangPS },
|
|
|
|
{ "tex2Dgrad", "V4", "F", "V2,,,", "S,F,,", EShLangPS },
|
|
|
|
{ "tex2Dlod", "V4", "F", "V2,V4", "S,F", EShLangPS },
|
|
|
|
{ "tex2Dproj", "V4", "F", "V2,V4", "S,F", EShLangPS },
|
|
|
|
{ "tex3D", "V4", "F", "V3,", "S,F", EShLangPS },
|
|
|
|
{ "tex3D", "V4", "F", "V3,,,", "S,F,,", EShLangPS },
|
|
|
|
{ "tex3Dbias", "V4", "F", "V3,V4", "S,F", EShLangPS },
|
|
|
|
{ "tex3Dgrad", "V4", "F", "V3,,,", "S,F,,", EShLangPS },
|
|
|
|
{ "tex3Dlod", "V4", "F", "V3,V4", "S,F", EShLangPS },
|
|
|
|
{ "tex3Dproj", "V4", "F", "V3,V4", "S,F", EShLangPS },
|
|
|
|
{ "texCUBE", "V4", "F", "V4,V3", "S,F", EShLangPS },
|
|
|
|
{ "texCUBE", "V4", "F", "V4,V3,,", "S,F,,", EShLangPS },
|
|
|
|
{ "texCUBEbias", "V4", "F", "V4,", "S,F", EShLangPS },
|
|
|
|
{ "texCUBEgrad", "V4", "F", "V4,V3,,", "S,F,,", EShLangPS },
|
|
|
|
{ "texCUBElod", "V4", "F", "V4,", "S,F", EShLangPS },
|
|
|
|
{ "texCUBEproj", "V4", "F", "V4,", "S,F", EShLangPS },
|
2016-11-15 10:11:04 -07:00
|
|
|
{ "transpose", "^M", nullptr, "M", "FUIB", EShLangAll },
|
2016-07-22 08:28:11 -06:00
|
|
|
{ "trunc", nullptr, nullptr, "SVM", "F", EShLangAll },
|
2016-05-26 10:10:16 -06:00
|
|
|
|
2016-06-29 10:58:58 -06:00
|
|
|
// Texture object methods. Return type can be overridden by shader declaration.
|
2016-07-22 08:28:11 -06:00
|
|
|
// !O = no offset, O = offset
|
2016-08-11 07:29:30 -06:00
|
|
|
{ "Sample", /*!O*/ "V4", nullptr, "%@,S,V", "FIU,S,F", EShLangPS },
|
|
|
|
{ "Sample", /* O*/ "V4", nullptr, "%@,S,V,", "FIU,S,F,I", EShLangPS },
|
2016-07-14 14:45:14 -06:00
|
|
|
|
2016-08-11 07:29:30 -06:00
|
|
|
{ "SampleBias", /*!O*/ "V4", nullptr, "%@,S,V,S", "FIU,S,F,", EShLangPS },
|
|
|
|
{ "SampleBias", /* O*/ "V4", nullptr, "%@,S,V,S,V", "FIU,S,F,,I", EShLangPS },
|
2016-07-14 14:45:14 -06:00
|
|
|
|
2016-07-19 14:28:05 -06:00
|
|
|
// TODO: FXC accepts int/uint samplers here. unclear what that means.
|
2016-08-11 07:29:30 -06:00
|
|
|
{ "SampleCmp", /*!O*/ "S", "F", "%@,S,V,S", "FIU,s,F,", EShLangPS },
|
|
|
|
{ "SampleCmp", /* O*/ "S", "F", "%@,S,V,S,V", "FIU,s,F,,I", EShLangPS },
|
2016-07-14 14:45:14 -06:00
|
|
|
|
2016-07-19 14:28:05 -06:00
|
|
|
// TODO: FXC accepts int/uint samplers here. unclear what that means.
|
2016-08-11 07:29:30 -06:00
|
|
|
{ "SampleCmpLevelZero", /*!O*/ "S", "F", "%@,S,V,S", "FIU,s,F,F", EShLangPS },
|
|
|
|
{ "SampleCmpLevelZero", /* O*/ "S", "F", "%@,S,V,S,V", "FIU,s,F,F,I", EShLangPS },
|
2016-07-22 08:28:11 -06:00
|
|
|
|
|
|
|
{ "SampleGrad", /*!O*/ "V4", nullptr, "%@,S,V,,", "FIU,S,F,,", EShLangAll },
|
|
|
|
{ "SampleGrad", /* O*/ "V4", nullptr, "%@,S,V,,,", "FIU,S,F,,,I", EShLangAll },
|
|
|
|
|
|
|
|
{ "SampleLevel", /*!O*/ "V4", nullptr, "%@,S,V,S", "FIU,S,F,", EShLangAll },
|
|
|
|
{ "SampleLevel", /* O*/ "V4", nullptr, "%@,S,V,S,V", "FIU,S,F,,I", EShLangAll },
|
|
|
|
|
2016-10-14 16:40:32 -06:00
|
|
|
{ "Load", /*!O*/ "V4", nullptr, "%@,V", "FIU,I", EShLangAll },
|
2016-07-22 08:28:11 -06:00
|
|
|
{ "Load", /* O*/ "V4", nullptr, "%@,V,V", "FIU,I,I", EShLangAll },
|
2016-07-26 15:19:28 -06:00
|
|
|
{ "Load", /* +sampleidex*/ "V4", nullptr, "$&,V,S", "FIU,I,I", EShLangAll },
|
|
|
|
{ "Load", /* +samplindex, offset*/ "V4", nullptr, "$&,V,S,V", "FIU,I,I,I", EShLangAll },
|
2016-07-22 08:28:11 -06:00
|
|
|
|
2016-10-04 16:58:14 -06:00
|
|
|
// RWTexture loads
|
|
|
|
{ "Load", "V4", nullptr, "!#,V", "FIU,I", EShLangAll },
|
2016-10-14 16:40:32 -06:00
|
|
|
// (RW)Buffer loads
|
HLSL: add intrinsic function implicit promotions
This PR handles implicit promotions for intrinsics when there is no exact match,
such as for example clamp(int, bool, float). In this case the int and bool will
be promoted to a float, and the clamp(float, float, float) form used.
These promotions can be mixed with shape conversions, e.g, clamp(int, bool2, float2).
Output conversions are handled either via the existing addOutputArgumentConversion
function, which this PR generalizes to handle either aggregates or unaries, or by
intrinsic decomposition. If there are methods or intrinsics to be decomposed,
then decomposition is responsible for any output conversions, which turns out to
happen automatically in all current cases. This can be revisited once inout
conversions are in place.
Some cases of actual ambiguity were fixed in several tests, e.g, spv.register.autoassign.*
Some intrinsics with only uint versions were expanded to signed ints natively, where the
underlying AST and SPIR-V supports that. E.g, countbits. This avoids extraneous
conversion nodes.
A new function promoteAggregate is added, and used by findFunction. This is essentially
a generalization of the "promote 1st or 2nd arg" algorithm in promoteBinary.
The actual selection proceeds in three steps, as described in the comments in
hlslParseContext::findFunction:
1. Attempt an exact match. If found, use it.
2. If not, obtain the operator from step 1, and promote arguments.
3. Re-select the intrinsic overload from the results of step 2.
2016-11-02 12:42:34 -06:00
|
|
|
{ "Load", "V4", nullptr, "~*1,V", "FIU,I", EShLangAll },
|
2016-10-04 16:58:14 -06:00
|
|
|
|
2016-07-31 10:37:02 -06:00
|
|
|
{ "Gather", /*!O*/ "V4", nullptr, "%@,S,V", "FIU,S,F", EShLangAll },
|
|
|
|
{ "Gather", /* O*/ "V4", nullptr, "%@,S,V,V", "FIU,S,F,I", EShLangAll },
|
2016-06-29 10:58:58 -06:00
|
|
|
|
2016-08-11 07:29:30 -06:00
|
|
|
{ "CalculateLevelOfDetail", "S", "F", "%@,S,V", "FUI,S,F", EShLangPS },
|
|
|
|
{ "CalculateLevelOfDetailUnclamped", "S", "F", "%@,S,V", "FUI,S,F", EShLangPS },
|
2016-07-26 08:57:53 -06:00
|
|
|
|
|
|
|
{ "GetSamplePosition", "V2", "F", "$&2,S", "FUI,I", EShLangVSPSGS },
|
|
|
|
|
2017-01-06 00:34:48 -07:00
|
|
|
//
|
2016-07-15 11:22:24 -06:00
|
|
|
// UINT Width
|
|
|
|
// UINT MipLevel, UINT Width, UINT NumberOfLevels
|
2016-10-04 16:58:14 -06:00
|
|
|
{ "GetDimensions", /* 1D */ "-", "-", "%!~1,>S", "FUI,U", EShLangAll },
|
|
|
|
{ "GetDimensions", /* 1D */ "-", "-", "%!~1,>S", "FUI,F", EShLangAll },
|
2016-07-22 08:28:11 -06:00
|
|
|
{ "GetDimensions", /* 1D */ "-", "-", "%1,S,>S,", "FUI,U,,", EShLangAll },
|
|
|
|
{ "GetDimensions", /* 1D */ "-", "-", "%1,S,>S,", "FUI,U,F,", EShLangAll },
|
2016-07-15 11:22:24 -06:00
|
|
|
|
|
|
|
// UINT Width, UINT Elements
|
|
|
|
// UINT MipLevel, UINT Width, UINT Elements, UINT NumberOfLevels
|
2016-10-04 16:58:14 -06:00
|
|
|
{ "GetDimensions", /* 1DArray */ "-", "-", "@#1,>S,", "FUI,U,", EShLangAll },
|
|
|
|
{ "GetDimensions", /* 1DArray */ "-", "-", "@#1,>S,", "FUI,F,", EShLangAll },
|
2016-07-22 08:28:11 -06:00
|
|
|
{ "GetDimensions", /* 1DArray */ "-", "-", "@1,S,>S,,", "FUI,U,,,", EShLangAll },
|
|
|
|
{ "GetDimensions", /* 1DArray */ "-", "-", "@1,S,>S,,", "FUI,U,F,,", EShLangAll },
|
2016-07-15 11:22:24 -06:00
|
|
|
|
|
|
|
// UINT Width, UINT Height
|
|
|
|
// UINT MipLevel, UINT Width, UINT Height, UINT NumberOfLevels
|
2016-10-04 16:58:14 -06:00
|
|
|
{ "GetDimensions", /* 2D */ "-", "-", "%!2,>S,", "FUI,U,", EShLangAll },
|
|
|
|
{ "GetDimensions", /* 2D */ "-", "-", "%!2,>S,", "FUI,F,", EShLangAll },
|
2016-07-22 08:28:11 -06:00
|
|
|
{ "GetDimensions", /* 2D */ "-", "-", "%2,S,>S,,", "FUI,U,,,", EShLangAll },
|
|
|
|
{ "GetDimensions", /* 2D */ "-", "-", "%2,S,>S,,", "FUI,U,F,,", EShLangAll },
|
2016-07-15 11:22:24 -06:00
|
|
|
|
|
|
|
// UINT Width, UINT Height, UINT Elements
|
|
|
|
// UINT MipLevel, UINT Width, UINT Height, UINT Elements, UINT NumberOfLevels
|
2016-10-04 16:58:14 -06:00
|
|
|
{ "GetDimensions", /* 2DArray */ "-", "-", "@#2,>S,,", "FUI,U,,", EShLangAll },
|
|
|
|
{ "GetDimensions", /* 2DArray */ "-", "-", "@#2,>S,,", "FUI,F,F,F", EShLangAll },
|
2016-07-22 08:28:11 -06:00
|
|
|
{ "GetDimensions", /* 2DArray */ "-", "-", "@2,S,>S,,,", "FUI,U,,,,", EShLangAll },
|
|
|
|
{ "GetDimensions", /* 2DArray */ "-", "-", "@2,S,>S,,,", "FUI,U,F,,,", EShLangAll },
|
2016-07-15 11:22:24 -06:00
|
|
|
|
|
|
|
// UINT Width, UINT Height, UINT Depth
|
|
|
|
// UINT MipLevel, UINT Width, UINT Height, UINT Depth, UINT NumberOfLevels
|
2016-10-04 16:58:14 -06:00
|
|
|
{ "GetDimensions", /* 3D */ "-", "-", "%!3,>S,,", "FUI,U,,", EShLangAll },
|
|
|
|
{ "GetDimensions", /* 3D */ "-", "-", "%!3,>S,,", "FUI,F,,", EShLangAll },
|
2016-07-22 08:28:11 -06:00
|
|
|
{ "GetDimensions", /* 3D */ "-", "-", "%3,S,>S,,,", "FUI,U,,,,", EShLangAll },
|
|
|
|
{ "GetDimensions", /* 3D */ "-", "-", "%3,S,>S,,,", "FUI,U,F,,,", EShLangAll },
|
2016-07-15 11:22:24 -06:00
|
|
|
|
|
|
|
// UINT Width, UINT Height
|
|
|
|
// UINT MipLevel, UINT Width, UINT Height, UINT NumberOfLevels
|
2016-07-22 08:28:11 -06:00
|
|
|
{ "GetDimensions", /* Cube */ "-", "-", "%4,>S,", "FUI,U,", EShLangAll },
|
|
|
|
{ "GetDimensions", /* Cube */ "-", "-", "%4,>S,", "FUI,F,", EShLangAll },
|
|
|
|
{ "GetDimensions", /* Cube */ "-", "-", "%4,S,>S,,", "FUI,U,,,", EShLangAll },
|
|
|
|
{ "GetDimensions", /* Cube */ "-", "-", "%4,S,>S,,", "FUI,U,F,,", EShLangAll },
|
2016-07-15 11:22:24 -06:00
|
|
|
|
|
|
|
// UINT Width, UINT Height, UINT Elements
|
|
|
|
// UINT MipLevel, UINT Width, UINT Height, UINT Elements, UINT NumberOfLevels
|
2016-07-22 08:28:11 -06:00
|
|
|
{ "GetDimensions", /* CubeArray */ "-", "-", "@4,>S,,", "FUI,U,,", EShLangAll },
|
|
|
|
{ "GetDimensions", /* CubeArray */ "-", "-", "@4,>S,,", "FUI,F,,", EShLangAll },
|
|
|
|
{ "GetDimensions", /* CubeArray */ "-", "-", "@4,S,>S,,,", "FUI,U,,,,", EShLangAll },
|
|
|
|
{ "GetDimensions", /* CubeArray */ "-", "-", "@4,S,>S,,,", "FUI,U,F,,,", EShLangAll },
|
2016-07-15 11:22:24 -06:00
|
|
|
|
|
|
|
// UINT Width, UINT Height, UINT Samples
|
|
|
|
// UINT Width, UINT Height, UINT Elements, UINT Samples
|
2016-07-31 10:37:02 -06:00
|
|
|
{ "GetDimensions", /* 2DMS */ "-", "-", "$2,>S,,", "FUI,U,,", EShLangAll },
|
|
|
|
{ "GetDimensions", /* 2DMS */ "-", "-", "$2,>S,,", "FUI,U,,", EShLangAll },
|
|
|
|
{ "GetDimensions", /* 2DMSArray */ "-", "-", "&2,>S,,,", "FUI,U,,,", EShLangAll },
|
|
|
|
{ "GetDimensions", /* 2DMSArray */ "-", "-", "&2,>S,,,", "FUI,U,,,", EShLangAll },
|
|
|
|
|
|
|
|
// SM5 texture methods
|
|
|
|
{ "GatherRed", /*!O*/ "V4", nullptr, "%@,S,V", "FIU,S,F", EShLangAll },
|
|
|
|
{ "GatherRed", /* O*/ "V4", nullptr, "%@,S,V,", "FIU,S,F,I", EShLangAll },
|
|
|
|
{ "GatherRed", /* O, status*/ "V4", nullptr, "%@,S,V,,>S", "FIU,S,F,I,U", EShLangAll },
|
|
|
|
{ "GatherRed", /* O-4 */ "V4", nullptr, "%@,S,V,,,,", "FIU,S,F,I,,,", EShLangAll },
|
|
|
|
{ "GatherRed", /* O-4, status */"V4", nullptr, "%@,S,V,,,,,S", "FIU,S,F,I,,,,U",EShLangAll },
|
|
|
|
|
|
|
|
{ "GatherGreen", /*!O*/ "V4", nullptr, "%@,S,V", "FIU,S,F", EShLangAll },
|
|
|
|
{ "GatherGreen", /* O*/ "V4", nullptr, "%@,S,V,", "FIU,S,F,I", EShLangAll },
|
|
|
|
{ "GatherGreen", /* O, status*/ "V4", nullptr, "%@,S,V,,>S", "FIU,S,F,I,U", EShLangAll },
|
|
|
|
{ "GatherGreen", /* O-4 */ "V4", nullptr, "%@,S,V,,,,", "FIU,S,F,I,,,", EShLangAll },
|
|
|
|
{ "GatherGreen", /* O-4, status */"V4", nullptr, "%@,S,V,,,,,S", "FIU,S,F,I,,,,U",EShLangAll },
|
|
|
|
|
|
|
|
{ "GatherBlue", /*!O*/ "V4", nullptr, "%@,S,V", "FIU,S,F", EShLangAll },
|
|
|
|
{ "GatherBlue", /* O*/ "V4", nullptr, "%@,S,V,", "FIU,S,F,I", EShLangAll },
|
|
|
|
{ "GatherBlue", /* O, status*/ "V4", nullptr, "%@,S,V,,>S", "FIU,S,F,I,U", EShLangAll },
|
|
|
|
{ "GatherBlue", /* O-4 */ "V4", nullptr, "%@,S,V,,,,", "FIU,S,F,I,,,", EShLangAll },
|
|
|
|
{ "GatherBlue", /* O-4, status */"V4", nullptr, "%@,S,V,,,,,S", "FIU,S,F,I,,,,U",EShLangAll },
|
|
|
|
|
|
|
|
{ "GatherAlpha", /*!O*/ "V4", nullptr, "%@,S,V", "FIU,S,F", EShLangAll },
|
|
|
|
{ "GatherAlpha", /* O*/ "V4", nullptr, "%@,S,V,", "FIU,S,F,I", EShLangAll },
|
|
|
|
{ "GatherAlpha", /* O, status*/ "V4", nullptr, "%@,S,V,,>S", "FIU,S,F,I,U", EShLangAll },
|
|
|
|
{ "GatherAlpha", /* O-4 */ "V4", nullptr, "%@,S,V,,,,", "FIU,S,F,I,,,", EShLangAll },
|
|
|
|
{ "GatherAlpha", /* O-4, status */"V4", nullptr, "%@,S,V,,,,,S", "FIU,S,F,I,,,,U",EShLangAll },
|
|
|
|
|
|
|
|
{ "GatherCmpRed", /*!O*/ "V4", nullptr, "%@,S,V,S", "FIU,s,F,", EShLangAll },
|
|
|
|
{ "GatherCmpRed", /* O*/ "V4", nullptr, "%@,S,V,S,V", "FIU,s,F,,I", EShLangAll },
|
|
|
|
{ "GatherCmpRed", /* O, status*/ "V4", nullptr, "%@,S,V,S,V,>S", "FIU,s,F,,I,U", EShLangAll },
|
|
|
|
{ "GatherCmpRed", /* O-4 */ "V4", nullptr, "%@,S,V,S,V,,,", "FIU,s,F,,I,,,", EShLangAll },
|
|
|
|
{ "GatherCmpRed", /* O-4, status */"V4", nullptr, "%@,S,V,S,V,,V,S","FIU,s,F,,I,,,,U",EShLangAll },
|
|
|
|
|
|
|
|
{ "GatherCmpGreen", /*!O*/ "V4", nullptr, "%@,S,V,S", "FIU,s,F,", EShLangAll },
|
|
|
|
{ "GatherCmpGreen", /* O*/ "V4", nullptr, "%@,S,V,S,V", "FIU,s,F,,I", EShLangAll },
|
|
|
|
{ "GatherCmpGreen", /* O, status*/ "V4", nullptr, "%@,S,V,S,V,>S", "FIU,s,F,,I,U", EShLangAll },
|
|
|
|
{ "GatherCmpGreen", /* O-4 */ "V4", nullptr, "%@,S,V,S,V,,,", "FIU,s,F,,I,,,", EShLangAll },
|
|
|
|
{ "GatherCmpGreen", /* O-4, status */"V4", nullptr, "%@,S,V,S,V,,,,S","FIU,s,F,,I,,,,U",EShLangAll },
|
|
|
|
|
|
|
|
{ "GatherCmpBlue", /*!O*/ "V4", nullptr, "%@,S,V,S", "FIU,s,F,", EShLangAll },
|
|
|
|
{ "GatherCmpBlue", /* O*/ "V4", nullptr, "%@,S,V,S,V", "FIU,s,F,,I", EShLangAll },
|
|
|
|
{ "GatherCmpBlue", /* O, status*/ "V4", nullptr, "%@,S,V,S,V,>S", "FIU,s,F,,I,U", EShLangAll },
|
|
|
|
{ "GatherCmpBlue", /* O-4 */ "V4", nullptr, "%@,S,V,S,V,,,", "FIU,s,F,,I,,,", EShLangAll },
|
|
|
|
{ "GatherCmpBlue", /* O-4, status */"V4", nullptr, "%@,S,V,S,V,,,,S","FIU,s,F,,I,,,,U",EShLangAll },
|
|
|
|
|
|
|
|
{ "GatherCmpAlpha", /*!O*/ "V4", nullptr, "%@,S,V,S", "FIU,s,F,", EShLangAll },
|
|
|
|
{ "GatherCmpAlpha", /* O*/ "V4", nullptr, "%@,S,V,S,V", "FIU,s,F,,I", EShLangAll },
|
|
|
|
{ "GatherCmpAlpha", /* O, status*/ "V4", nullptr, "%@,S,V,S,V,>S", "FIU,s,F,,I,U", EShLangAll },
|
|
|
|
{ "GatherCmpAlpha", /* O-4 */ "V4", nullptr, "%@,S,V,S,V,,,", "FIU,s,F,,I,,,", EShLangAll },
|
|
|
|
{ "GatherCmpAlpha", /* O-4, status */"V4", nullptr, "%@,S,V,S,V,,,,S","FIU,s,F,,I,,,,U",EShLangAll },
|
|
|
|
|
2016-11-17 15:04:20 -07:00
|
|
|
// geometry methods
|
|
|
|
{ "Append", "-", "-", "-", "-", EShLangGS },
|
|
|
|
{ "RestartStrip", "-", "-", "-", "-", EShLangGS },
|
|
|
|
|
2016-05-26 10:10:16 -06:00
|
|
|
// Mark end of list, since we want to avoid a range-based for, as some compilers don't handle it yet.
|
|
|
|
{ nullptr, nullptr, nullptr, nullptr, nullptr, 0 },
|
|
|
|
};
|
|
|
|
|
|
|
|
// Create prototypes for the intrinsics. TODO: Avoid ranged based for until all compilers can handle it.
|
|
|
|
for (int icount = 0; hlslIntrinsics[icount].name; ++icount) {
|
|
|
|
const auto& intrinsic = hlslIntrinsics[icount];
|
|
|
|
|
|
|
|
for (int stage = 0; stage < EShLangCount; ++stage) { // for each stage...
|
|
|
|
if ((intrinsic.stage & (1<<stage)) == 0) // skip inapplicable stages
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// reference to either the common builtins, or stage specific builtins.
|
|
|
|
TString& s = (intrinsic.stage == EShLangAll) ? commonBuiltins : stageBuiltins[stage];
|
|
|
|
|
|
|
|
for (const char* argOrder = intrinsic.argOrder; !IsEndOfArg(argOrder); ++argOrder) { // for each order...
|
2016-07-12 14:45:05 -06:00
|
|
|
const bool isTexture = IsTextureType(*argOrder);
|
2016-10-04 16:58:14 -06:00
|
|
|
const bool isArrayed = IsArrayed(*argOrder);
|
2016-07-26 15:19:28 -06:00
|
|
|
const bool isMS = IsTextureMS(*argOrder);
|
2016-07-27 15:46:48 -06:00
|
|
|
const bool isBuffer = IsBuffer(*argOrder);
|
2016-10-04 16:58:14 -06:00
|
|
|
const bool isImage = IsImage(*argOrder);
|
|
|
|
const bool mipInCoord = HasMipInCoord(intrinsic.name, isMS, isBuffer, isImage);
|
2016-07-15 11:22:24 -06:00
|
|
|
const int fixedVecSize = FixedVecSize(argOrder);
|
2016-07-19 14:28:05 -06:00
|
|
|
const int coordArg = CoordinateArgPos(intrinsic.name, isTexture);
|
2016-05-26 10:10:16 -06:00
|
|
|
|
|
|
|
// calculate min and max vector and matrix dimensions
|
|
|
|
int dim0Min = 1;
|
|
|
|
int dim0Max = 1;
|
|
|
|
int dim1Min = 1;
|
|
|
|
int dim1Max = 1;
|
|
|
|
|
|
|
|
FindVectorMatrixBounds(argOrder, fixedVecSize, dim0Min, dim0Max, dim1Min, dim1Max);
|
|
|
|
|
|
|
|
for (const char* argType = intrinsic.argType; !IsEndOfArg(argType); ++argType) { // for each type...
|
|
|
|
for (int dim0 = dim0Min; dim0 <= dim0Max; ++dim0) { // for each dim 0...
|
|
|
|
for (int dim1 = dim1Min; dim1 <= dim1Max; ++dim1) { // for each dim 1...
|
|
|
|
const char* retOrder = intrinsic.retOrder ? intrinsic.retOrder : argOrder;
|
|
|
|
const char* retType = intrinsic.retType ? intrinsic.retType : argType;
|
|
|
|
|
2016-11-15 10:11:04 -07:00
|
|
|
if (!IsValid(intrinsic.name, *retOrder, *retType, *argOrder, *argType, dim0, dim1))
|
2016-05-26 10:10:16 -06:00
|
|
|
continue;
|
|
|
|
|
2016-07-12 14:45:05 -06:00
|
|
|
// Reject some forms of sample methods that don't exist.
|
2016-07-14 14:45:14 -06:00
|
|
|
if (isTexture && IsIllegalSample(intrinsic.name, argOrder, dim0))
|
2016-07-12 14:45:05 -06:00
|
|
|
continue;
|
|
|
|
|
2016-05-26 10:10:16 -06:00
|
|
|
AppendTypeName(s, retOrder, retType, dim0, dim1); // add return type
|
|
|
|
s.append(" "); // space between type and name
|
|
|
|
s.append(intrinsic.name); // intrinsic name
|
|
|
|
s.append("("); // open paren
|
|
|
|
|
2016-07-22 08:28:11 -06:00
|
|
|
const char* prevArgOrder = nullptr;
|
|
|
|
const char* prevArgType = nullptr;
|
|
|
|
|
2016-05-26 10:10:16 -06:00
|
|
|
// Append argument types, if any.
|
|
|
|
for (int arg = 0; ; ++arg) {
|
|
|
|
const char* nthArgOrder(NthArg(argOrder, arg));
|
|
|
|
const char* nthArgType(NthArg(argType, arg));
|
|
|
|
|
|
|
|
if (nthArgOrder == nullptr || nthArgType == nullptr)
|
|
|
|
break;
|
|
|
|
|
2016-07-12 14:45:05 -06:00
|
|
|
// cube textures use vec3 coordinates
|
|
|
|
int argDim0 = isTexture && arg > 0 ? std::min(dim0, 3) : dim0;
|
|
|
|
|
2016-07-22 08:28:11 -06:00
|
|
|
s.append(arg > 0 ? ", ": ""); // comma separator if needed
|
|
|
|
|
|
|
|
const char* orderBegin = nthArgOrder;
|
|
|
|
nthArgOrder = IoParam(s, nthArgOrder);
|
|
|
|
|
|
|
|
// Comma means use the previous argument order and type.
|
|
|
|
HandleRepeatArg(nthArgOrder, prevArgOrder, orderBegin);
|
|
|
|
HandleRepeatArg(nthArgType, prevArgType, nthArgType);
|
|
|
|
|
|
|
|
// In case the repeated arg has its own I/O marker
|
|
|
|
nthArgOrder = IoParam(s, nthArgOrder);
|
|
|
|
|
2016-07-26 08:57:53 -06:00
|
|
|
// arrayed textures have one extra coordinate dimension, except for
|
|
|
|
// the CalculateLevelOfDetail family.
|
|
|
|
if (isArrayed && arg == coordArg && !NoArrayCoord(intrinsic.name))
|
2016-07-19 14:28:05 -06:00
|
|
|
argDim0++;
|
|
|
|
|
|
|
|
// Some texture methods use an addition arg dimension to hold mip
|
|
|
|
if (arg == coordArg && mipInCoord)
|
2016-07-12 14:45:05 -06:00
|
|
|
argDim0++;
|
|
|
|
|
2016-06-29 10:58:58 -06:00
|
|
|
// For textures, the 1D case isn't a 1-vector, but a scalar.
|
2016-07-12 14:45:05 -06:00
|
|
|
if (isTexture && argDim0 == 1 && arg > 0 && *nthArgOrder == 'V')
|
2016-06-29 10:58:58 -06:00
|
|
|
nthArgOrder = "S";
|
|
|
|
|
|
|
|
AppendTypeName(s, nthArgOrder, nthArgType, argDim0, dim1); // Add arguments
|
2016-05-26 10:10:16 -06:00
|
|
|
}
|
2017-01-06 00:34:48 -07:00
|
|
|
|
2016-05-26 10:10:16 -06:00
|
|
|
s.append(");\n"); // close paren and trailing semicolon
|
2016-07-22 08:28:11 -06:00
|
|
|
} // dim 1 loop
|
|
|
|
} // dim 0 loop
|
|
|
|
} // arg type loop
|
2016-05-26 10:10:16 -06:00
|
|
|
|
2016-07-15 11:22:24 -06:00
|
|
|
// skip over special characters
|
2016-07-22 08:28:11 -06:00
|
|
|
if (isTexture && isalpha(argOrder[1]))
|
2016-07-15 11:22:24 -06:00
|
|
|
++argOrder;
|
2017-01-06 00:34:48 -07:00
|
|
|
if (isdigit(argOrder[1]))
|
2016-05-26 10:10:16 -06:00
|
|
|
++argOrder;
|
2016-07-22 08:28:11 -06:00
|
|
|
} // arg order loop
|
2017-01-06 00:34:48 -07:00
|
|
|
|
2016-05-26 10:10:16 -06:00
|
|
|
if (intrinsic.stage == EShLangAll) // common builtins are only added once.
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-20 13:26:59 -06:00
|
|
|
createMatTimesMat(); // handle this case separately, for convenience
|
|
|
|
|
2016-05-26 10:10:16 -06:00
|
|
|
// printf("Common:\n%s\n", getCommonString().c_str());
|
|
|
|
// printf("Frag:\n%s\n", getStageString(EShLangFragment).c_str());
|
|
|
|
// printf("Vertex:\n%s\n", getStageString(EShLangVertex).c_str());
|
|
|
|
// printf("Geo:\n%s\n", getStageString(EShLangGeometry).c_str());
|
|
|
|
// printf("TessCtrl:\n%s\n", getStageString(EShLangTessControl).c_str());
|
|
|
|
// printf("TessEval:\n%s\n", getStageString(EShLangTessEvaluation).c_str());
|
|
|
|
// printf("Compute:\n%s\n", getStageString(EShLangCompute).c_str());
|
2016-05-20 13:45:20 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Add context-dependent built-in functions and variables that are present
|
|
|
|
// for the given version and profile. All the results are put into just the
|
|
|
|
// commonBuiltins, because it is called for just a specific stage. So,
|
|
|
|
// add stage-specific entries to the commonBuiltins, and only if that stage
|
|
|
|
// was requested.
|
|
|
|
//
|
2016-07-08 22:09:10 -06:00
|
|
|
void TBuiltInParseablesHlsl::initialize(const TBuiltInResource& /*resources*/, int /*version*/, EProfile /*profile*/,
|
|
|
|
const SpvVersion& /*spvVersion*/, EShLanguage /*language*/)
|
2016-05-20 13:45:20 -06:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Finish adding/processing context-independent built-in symbols.
|
|
|
|
// 1) Programmatically add symbols that could not be added by simple text strings above.
|
|
|
|
// 2) Map built-in functions to operators, for those that will turn into an operation node
|
|
|
|
// instead of remaining a function call.
|
|
|
|
// 3) Tag extension-related symbols added to their base version with their extensions, so
|
|
|
|
// that if an early version has the extension turned off, there is an error reported on use.
|
|
|
|
//
|
2016-07-08 22:09:10 -06:00
|
|
|
void TBuiltInParseablesHlsl::identifyBuiltIns(int /*version*/, EProfile /*profile*/, const SpvVersion& /*spvVersion*/, EShLanguage /*language*/,
|
2016-05-20 13:45:20 -06:00
|
|
|
TSymbolTable& symbolTable)
|
|
|
|
{
|
2016-06-09 08:57:35 -06:00
|
|
|
// symbolTable.relateToOperator("abort", EOpAbort);
|
2016-05-26 10:10:16 -06:00
|
|
|
symbolTable.relateToOperator("abs", EOpAbs);
|
|
|
|
symbolTable.relateToOperator("acos", EOpAcos);
|
|
|
|
symbolTable.relateToOperator("all", EOpAll);
|
2016-06-15 09:50:24 -06:00
|
|
|
symbolTable.relateToOperator("AllMemoryBarrier", EOpMemoryBarrier);
|
|
|
|
symbolTable.relateToOperator("AllMemoryBarrierWithGroupSync", EOpAllMemoryBarrierWithGroupSync);
|
2016-05-26 10:10:16 -06:00
|
|
|
symbolTable.relateToOperator("any", EOpAny);
|
2016-06-22 15:20:14 -06:00
|
|
|
symbolTable.relateToOperator("asdouble", EOpAsDouble);
|
2016-06-13 09:22:28 -06:00
|
|
|
symbolTable.relateToOperator("asfloat", EOpIntBitsToFloat);
|
2016-05-26 10:10:16 -06:00
|
|
|
symbolTable.relateToOperator("asin", EOpAsin);
|
2016-06-13 09:22:28 -06:00
|
|
|
symbolTable.relateToOperator("asint", EOpFloatBitsToInt);
|
|
|
|
symbolTable.relateToOperator("asuint", EOpFloatBitsToUint);
|
2016-05-26 10:10:16 -06:00
|
|
|
symbolTable.relateToOperator("atan", EOpAtan);
|
|
|
|
symbolTable.relateToOperator("atan2", EOpAtan);
|
|
|
|
symbolTable.relateToOperator("ceil", EOpCeil);
|
|
|
|
// symbolTable.relateToOperator("CheckAccessFullyMapped");
|
|
|
|
symbolTable.relateToOperator("clamp", EOpClamp);
|
2016-06-09 08:57:35 -06:00
|
|
|
symbolTable.relateToOperator("clip", EOpClip);
|
2016-05-26 10:10:16 -06:00
|
|
|
symbolTable.relateToOperator("cos", EOpCos);
|
|
|
|
symbolTable.relateToOperator("cosh", EOpCosh);
|
|
|
|
symbolTable.relateToOperator("countbits", EOpBitCount);
|
|
|
|
symbolTable.relateToOperator("cross", EOpCross);
|
2017-01-03 14:42:18 -07:00
|
|
|
symbolTable.relateToOperator("D3DCOLORtoUBYTE4", EOpD3DCOLORtoUBYTE4);
|
2016-05-26 10:10:16 -06:00
|
|
|
symbolTable.relateToOperator("ddx", EOpDPdx);
|
|
|
|
symbolTable.relateToOperator("ddx_coarse", EOpDPdxCoarse);
|
|
|
|
symbolTable.relateToOperator("ddx_fine", EOpDPdxFine);
|
|
|
|
symbolTable.relateToOperator("ddy", EOpDPdy);
|
|
|
|
symbolTable.relateToOperator("ddy_coarse", EOpDPdyCoarse);
|
|
|
|
symbolTable.relateToOperator("ddy_fine", EOpDPdyFine);
|
|
|
|
symbolTable.relateToOperator("degrees", EOpDegrees);
|
|
|
|
symbolTable.relateToOperator("determinant", EOpDeterminant);
|
2016-06-29 10:58:58 -06:00
|
|
|
symbolTable.relateToOperator("DeviceMemoryBarrier", EOpGroupMemoryBarrier);
|
2016-06-15 09:50:24 -06:00
|
|
|
symbolTable.relateToOperator("DeviceMemoryBarrierWithGroupSync", EOpGroupMemoryBarrierWithGroupSync); // ...
|
2016-05-26 10:10:16 -06:00
|
|
|
symbolTable.relateToOperator("distance", EOpDistance);
|
|
|
|
symbolTable.relateToOperator("dot", EOpDot);
|
2016-06-09 08:57:35 -06:00
|
|
|
symbolTable.relateToOperator("dst", EOpDst);
|
2016-06-15 09:50:24 -06:00
|
|
|
// symbolTable.relateToOperator("errorf", EOpErrorf);
|
2016-05-26 10:10:16 -06:00
|
|
|
symbolTable.relateToOperator("EvaluateAttributeAtCentroid", EOpInterpolateAtCentroid);
|
|
|
|
symbolTable.relateToOperator("EvaluateAttributeAtSample", EOpInterpolateAtSample);
|
2016-06-15 09:50:24 -06:00
|
|
|
symbolTable.relateToOperator("EvaluateAttributeSnapped", EOpEvaluateAttributeSnapped);
|
2016-05-26 10:10:16 -06:00
|
|
|
symbolTable.relateToOperator("exp", EOpExp);
|
|
|
|
symbolTable.relateToOperator("exp2", EOpExp2);
|
2016-06-15 09:50:24 -06:00
|
|
|
symbolTable.relateToOperator("f16tof32", EOpF16tof32);
|
|
|
|
symbolTable.relateToOperator("f32tof16", EOpF32tof16);
|
2016-05-26 10:10:16 -06:00
|
|
|
symbolTable.relateToOperator("faceforward", EOpFaceForward);
|
|
|
|
symbolTable.relateToOperator("firstbithigh", EOpFindMSB);
|
|
|
|
symbolTable.relateToOperator("firstbitlow", EOpFindLSB);
|
|
|
|
symbolTable.relateToOperator("floor", EOpFloor);
|
|
|
|
symbolTable.relateToOperator("fma", EOpFma);
|
2016-06-09 08:57:35 -06:00
|
|
|
symbolTable.relateToOperator("fmod", EOpMod);
|
2016-05-26 10:10:16 -06:00
|
|
|
symbolTable.relateToOperator("frac", EOpFract);
|
|
|
|
symbolTable.relateToOperator("frexp", EOpFrexp);
|
|
|
|
symbolTable.relateToOperator("fwidth", EOpFwidth);
|
|
|
|
// symbolTable.relateToOperator("GetRenderTargetSampleCount");
|
|
|
|
// symbolTable.relateToOperator("GetRenderTargetSamplePosition");
|
2016-06-15 09:50:24 -06:00
|
|
|
symbolTable.relateToOperator("GroupMemoryBarrier", EOpWorkgroupMemoryBarrier);
|
|
|
|
symbolTable.relateToOperator("GroupMemoryBarrierWithGroupSync", EOpWorkgroupMemoryBarrierWithGroupSync);
|
2016-06-13 09:22:28 -06:00
|
|
|
symbolTable.relateToOperator("InterlockedAdd", EOpInterlockedAdd);
|
|
|
|
symbolTable.relateToOperator("InterlockedAnd", EOpInterlockedAnd);
|
|
|
|
symbolTable.relateToOperator("InterlockedCompareExchange", EOpInterlockedCompareExchange);
|
|
|
|
symbolTable.relateToOperator("InterlockedCompareStore", EOpInterlockedCompareStore);
|
|
|
|
symbolTable.relateToOperator("InterlockedExchange", EOpInterlockedExchange);
|
|
|
|
symbolTable.relateToOperator("InterlockedMax", EOpInterlockedMax);
|
|
|
|
symbolTable.relateToOperator("InterlockedMin", EOpInterlockedMin);
|
|
|
|
symbolTable.relateToOperator("InterlockedOr", EOpInterlockedOr);
|
|
|
|
symbolTable.relateToOperator("InterlockedXor", EOpInterlockedXor);
|
2016-06-09 08:57:35 -06:00
|
|
|
symbolTable.relateToOperator("isfinite", EOpIsFinite);
|
2016-05-26 10:10:16 -06:00
|
|
|
symbolTable.relateToOperator("isinf", EOpIsInf);
|
|
|
|
symbolTable.relateToOperator("isnan", EOpIsNan);
|
|
|
|
symbolTable.relateToOperator("ldexp", EOpLdexp);
|
|
|
|
symbolTable.relateToOperator("length", EOpLength);
|
2016-06-20 13:26:59 -06:00
|
|
|
symbolTable.relateToOperator("lerp", EOpMix);
|
2016-06-15 09:50:24 -06:00
|
|
|
symbolTable.relateToOperator("lit", EOpLit);
|
2016-05-26 10:10:16 -06:00
|
|
|
symbolTable.relateToOperator("log", EOpLog);
|
2016-06-09 08:57:35 -06:00
|
|
|
symbolTable.relateToOperator("log10", EOpLog10);
|
2016-05-26 10:10:16 -06:00
|
|
|
symbolTable.relateToOperator("log2", EOpLog2);
|
2016-06-22 15:20:14 -06:00
|
|
|
symbolTable.relateToOperator("mad", EOpFma);
|
2016-05-26 10:10:16 -06:00
|
|
|
symbolTable.relateToOperator("max", EOpMax);
|
|
|
|
symbolTable.relateToOperator("min", EOpMin);
|
|
|
|
symbolTable.relateToOperator("modf", EOpModf);
|
2016-06-09 08:57:35 -06:00
|
|
|
// symbolTable.relateToOperator("msad4", EOpMsad4);
|
|
|
|
symbolTable.relateToOperator("mul", EOpGenMul);
|
2016-05-26 10:10:16 -06:00
|
|
|
// symbolTable.relateToOperator("noise", EOpNoise); // TODO: check return type
|
|
|
|
symbolTable.relateToOperator("normalize", EOpNormalize);
|
|
|
|
symbolTable.relateToOperator("pow", EOpPow);
|
2016-06-15 09:50:24 -06:00
|
|
|
// symbolTable.relateToOperator("printf", EOpPrintf);
|
2016-05-26 10:10:16 -06:00
|
|
|
// symbolTable.relateToOperator("Process2DQuadTessFactorsAvg");
|
|
|
|
// symbolTable.relateToOperator("Process2DQuadTessFactorsMax");
|
|
|
|
// symbolTable.relateToOperator("Process2DQuadTessFactorsMin");
|
|
|
|
// symbolTable.relateToOperator("ProcessIsolineTessFactors");
|
|
|
|
// symbolTable.relateToOperator("ProcessQuadTessFactorsAvg");
|
|
|
|
// symbolTable.relateToOperator("ProcessQuadTessFactorsMax");
|
|
|
|
// symbolTable.relateToOperator("ProcessQuadTessFactorsMin");
|
|
|
|
// symbolTable.relateToOperator("ProcessTriTessFactorsAvg");
|
|
|
|
// symbolTable.relateToOperator("ProcessTriTessFactorsMax");
|
|
|
|
// symbolTable.relateToOperator("ProcessTriTessFactorsMin");
|
|
|
|
symbolTable.relateToOperator("radians", EOpRadians);
|
2016-06-09 08:57:35 -06:00
|
|
|
symbolTable.relateToOperator("rcp", EOpRcp);
|
2016-05-26 10:10:16 -06:00
|
|
|
symbolTable.relateToOperator("reflect", EOpReflect);
|
|
|
|
symbolTable.relateToOperator("refract", EOpRefract);
|
|
|
|
symbolTable.relateToOperator("reversebits", EOpBitFieldReverse);
|
|
|
|
symbolTable.relateToOperator("round", EOpRoundEven);
|
|
|
|
symbolTable.relateToOperator("rsqrt", EOpInverseSqrt);
|
2016-06-09 08:57:35 -06:00
|
|
|
symbolTable.relateToOperator("saturate", EOpSaturate);
|
2016-05-26 10:10:16 -06:00
|
|
|
symbolTable.relateToOperator("sign", EOpSign);
|
|
|
|
symbolTable.relateToOperator("sin", EOpSin);
|
2016-06-09 08:57:35 -06:00
|
|
|
symbolTable.relateToOperator("sincos", EOpSinCos);
|
2016-05-26 10:10:16 -06:00
|
|
|
symbolTable.relateToOperator("sinh", EOpSinh);
|
|
|
|
symbolTable.relateToOperator("smoothstep", EOpSmoothStep);
|
|
|
|
symbolTable.relateToOperator("sqrt", EOpSqrt);
|
|
|
|
symbolTable.relateToOperator("step", EOpStep);
|
|
|
|
symbolTable.relateToOperator("tan", EOpTan);
|
|
|
|
symbolTable.relateToOperator("tanh", EOpTanh);
|
|
|
|
symbolTable.relateToOperator("tex1D", EOpTexture);
|
2016-06-20 13:26:59 -06:00
|
|
|
symbolTable.relateToOperator("tex1Dbias", EOpTextureBias);
|
2016-05-26 10:10:16 -06:00
|
|
|
symbolTable.relateToOperator("tex1Dgrad", EOpTextureGrad);
|
|
|
|
symbolTable.relateToOperator("tex1Dlod", EOpTextureLod);
|
|
|
|
symbolTable.relateToOperator("tex1Dproj", EOpTextureProj);
|
|
|
|
symbolTable.relateToOperator("tex2D", EOpTexture);
|
2016-06-20 13:26:59 -06:00
|
|
|
symbolTable.relateToOperator("tex2Dbias", EOpTextureBias);
|
2016-05-26 10:10:16 -06:00
|
|
|
symbolTable.relateToOperator("tex2Dgrad", EOpTextureGrad);
|
|
|
|
symbolTable.relateToOperator("tex2Dlod", EOpTextureLod);
|
2016-06-20 13:26:59 -06:00
|
|
|
symbolTable.relateToOperator("tex2Dproj", EOpTextureProj);
|
2016-05-26 10:10:16 -06:00
|
|
|
symbolTable.relateToOperator("tex3D", EOpTexture);
|
2016-06-20 13:26:59 -06:00
|
|
|
symbolTable.relateToOperator("tex3Dbias", EOpTextureBias);
|
2016-05-26 10:10:16 -06:00
|
|
|
symbolTable.relateToOperator("tex3Dgrad", EOpTextureGrad);
|
|
|
|
symbolTable.relateToOperator("tex3Dlod", EOpTextureLod);
|
2016-06-20 13:26:59 -06:00
|
|
|
symbolTable.relateToOperator("tex3Dproj", EOpTextureProj);
|
2016-05-26 10:10:16 -06:00
|
|
|
symbolTable.relateToOperator("texCUBE", EOpTexture);
|
2016-06-20 13:26:59 -06:00
|
|
|
symbolTable.relateToOperator("texCUBEbias", EOpTextureBias);
|
2016-05-26 10:10:16 -06:00
|
|
|
symbolTable.relateToOperator("texCUBEgrad", EOpTextureGrad);
|
|
|
|
symbolTable.relateToOperator("texCUBElod", EOpTextureLod);
|
2016-06-20 13:26:59 -06:00
|
|
|
symbolTable.relateToOperator("texCUBEproj", EOpTextureProj);
|
2016-05-26 10:10:16 -06:00
|
|
|
symbolTable.relateToOperator("transpose", EOpTranspose);
|
|
|
|
symbolTable.relateToOperator("trunc", EOpTrunc);
|
2016-06-29 10:58:58 -06:00
|
|
|
|
|
|
|
// Texture methods
|
|
|
|
symbolTable.relateToOperator("Sample", EOpMethodSample);
|
2016-07-14 14:45:14 -06:00
|
|
|
symbolTable.relateToOperator("SampleBias", EOpMethodSampleBias);
|
2016-07-19 14:28:05 -06:00
|
|
|
symbolTable.relateToOperator("SampleCmp", EOpMethodSampleCmp);
|
|
|
|
symbolTable.relateToOperator("SampleCmpLevelZero", EOpMethodSampleCmpLevelZero);
|
2016-07-14 14:45:14 -06:00
|
|
|
symbolTable.relateToOperator("SampleGrad", EOpMethodSampleGrad);
|
2016-07-21 15:02:16 -06:00
|
|
|
symbolTable.relateToOperator("SampleLevel", EOpMethodSampleLevel);
|
2016-07-20 16:34:44 -06:00
|
|
|
symbolTable.relateToOperator("Load", EOpMethodLoad);
|
2016-07-15 11:22:24 -06:00
|
|
|
symbolTable.relateToOperator("GetDimensions", EOpMethodGetDimensions);
|
2016-07-26 08:57:53 -06:00
|
|
|
symbolTable.relateToOperator("GetSamplePosition", EOpMethodGetSamplePosition);
|
2016-07-22 08:28:11 -06:00
|
|
|
symbolTable.relateToOperator("Gather", EOpMethodGather);
|
2016-07-26 08:57:53 -06:00
|
|
|
symbolTable.relateToOperator("CalculateLevelOfDetail", EOpMethodCalculateLevelOfDetail);
|
|
|
|
symbolTable.relateToOperator("CalculateLevelOfDetailUnclamped", EOpMethodCalculateLevelOfDetailUnclamped);
|
2016-07-31 10:37:02 -06:00
|
|
|
|
|
|
|
// SM5 Texture methods
|
|
|
|
symbolTable.relateToOperator("GatherRed", EOpMethodGatherRed);
|
|
|
|
symbolTable.relateToOperator("GatherGreen", EOpMethodGatherGreen);
|
|
|
|
symbolTable.relateToOperator("GatherBlue", EOpMethodGatherBlue);
|
|
|
|
symbolTable.relateToOperator("GatherAlpha", EOpMethodGatherAlpha);
|
|
|
|
symbolTable.relateToOperator("GatherCmpRed", EOpMethodGatherCmpRed);
|
|
|
|
symbolTable.relateToOperator("GatherCmpGreen", EOpMethodGatherCmpGreen);
|
|
|
|
symbolTable.relateToOperator("GatherCmpBlue", EOpMethodGatherCmpBlue);
|
|
|
|
symbolTable.relateToOperator("GatherCmpAlpha", EOpMethodGatherCmpAlpha);
|
2016-11-17 15:04:20 -07:00
|
|
|
|
|
|
|
// GS methods
|
|
|
|
symbolTable.relateToOperator("Append", EOpMethodAppend);
|
|
|
|
symbolTable.relateToOperator("RestartStrip", EOpMethodRestartStrip);
|
2016-05-20 13:45:20 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Add context-dependent (resource-specific) built-ins not handled by the above. These
|
2017-01-06 00:34:48 -07:00
|
|
|
// would be ones that need to be programmatically added because they cannot
|
2016-05-20 13:45:20 -06:00
|
|
|
// be added by simple text strings. For these, also
|
|
|
|
// 1) Map built-in functions to operators, for those that will turn into an operation node
|
|
|
|
// instead of remaining a function call.
|
|
|
|
// 2) Tag extension-related symbols added to their base version with their extensions, so
|
|
|
|
// that if an early version has the extension turned off, there is an error reported on use.
|
|
|
|
//
|
2016-07-08 22:09:10 -06:00
|
|
|
void TBuiltInParseablesHlsl::identifyBuiltIns(int /*version*/, EProfile /*profile*/, const SpvVersion& /*spvVersion*/, EShLanguage /*language*/,
|
|
|
|
TSymbolTable& /*symbolTable*/, const TBuiltInResource& /*resources*/)
|
2016-05-20 13:45:20 -06:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
} // end namespace glslang
|