HLSL: Add tx.GetDimensions method (uint returns only)
This commit is contained in:
@@ -661,14 +661,14 @@ bool HlslGrammar::acceptSamplerType(TType& type)
|
||||
// read sampler type
|
||||
const EHlslTokenClass samplerType = peek();
|
||||
|
||||
TSamplerDim dim = EsdNone;
|
||||
// TSamplerDim dim = EsdNone;
|
||||
|
||||
switch (samplerType) {
|
||||
case EHTokSampler: break;
|
||||
case EHTokSampler1d: dim = Esd1D; break;
|
||||
case EHTokSampler2d: dim = Esd2D; break;
|
||||
case EHTokSampler3d: dim = Esd3D; break;
|
||||
case EHTokSamplerCube: dim = EsdCube; break;
|
||||
case EHTokSampler1d: /*dim = Esd1D*/; break;
|
||||
case EHTokSampler2d: /*dim = Esd2D*/; break;
|
||||
case EHTokSampler3d: /*dim = Esd3D*/; break;
|
||||
case EHTokSamplerCube: /*dim = EsdCube*/; break;
|
||||
case EHTokSamplerState: break;
|
||||
case EHTokSamplerComparisonState: break;
|
||||
default:
|
||||
|
||||
@@ -964,6 +964,105 @@ void HlslParseContext::decomposeSampleMethods(const TSourceLoc& loc, TIntermType
|
||||
break;
|
||||
}
|
||||
|
||||
case EOpMethodGetDimensions:
|
||||
{
|
||||
// AST returns a vector of results, which we break apart component-wise into
|
||||
// separate values to assign to the HLSL method's outputs, ala:
|
||||
// tx . GetDimensions(width, height);
|
||||
// float2 sizeQueryTemp = EOpTextureQuerySize
|
||||
// width = sizeQueryTemp.X;
|
||||
// height = sizeQueryTemp.Y;
|
||||
|
||||
TIntermTyped* argTex = argAggregate->getSequence()[0]->getAsTyped();
|
||||
const TType& texType = argTex->getType();
|
||||
|
||||
assert(texType.getBasicType() == EbtSampler);
|
||||
|
||||
const TSampler& texSampler = texType.getSampler();
|
||||
const TSamplerDim dim = texSampler.dim;
|
||||
const int numArgs = argAggregate->getSequence().size();
|
||||
|
||||
int numDims = 0;
|
||||
|
||||
switch (dim) {
|
||||
case Esd1D: numDims = 1; break; // W
|
||||
case Esd2D: numDims = 2; break; // W, H
|
||||
case Esd3D: numDims = 3; break; // W, H, D
|
||||
case EsdCube: numDims = 2; break; // W, H (cube)
|
||||
default:
|
||||
assert(0 && "unhandled texture dimension");
|
||||
}
|
||||
|
||||
// Arrayed adds another dimension for the number of array elements
|
||||
if (texSampler.isArrayed())
|
||||
++numDims;
|
||||
|
||||
// Establish whether we're querying mip levels
|
||||
const bool mipQuery = numArgs > (numDims + 1);
|
||||
|
||||
// AST assumes integer return. Will be converted to float if required.
|
||||
TIntermAggregate* sizeQuery = new TIntermAggregate(EOpTextureQuerySize);
|
||||
sizeQuery->getSequence().push_back(argTex);
|
||||
// If we're querying an explicit LOD, add the LOD, which is always arg #1
|
||||
if (mipQuery) {
|
||||
TIntermTyped* queryLod = argAggregate->getSequence()[1]->getAsTyped();
|
||||
sizeQuery->getSequence().push_back(queryLod);
|
||||
}
|
||||
sizeQuery->setType(TType(EbtUint, EvqTemporary, numDims));
|
||||
sizeQuery->setLoc(loc);
|
||||
|
||||
// Return value from size query
|
||||
TVariable* tempArg = makeInternalVariable("sizeQueryTemp", sizeQuery->getType());
|
||||
tempArg->getWritableType().getQualifier().makeTemporary();
|
||||
TIntermSymbol* sizeQueryReturn = intermediate.addSymbol(*tempArg, loc);
|
||||
|
||||
TIntermTyped* sizeQueryAssign = intermediate.addAssign(EOpAssign, sizeQueryReturn, sizeQuery, loc);
|
||||
|
||||
// Compound statement for assigning outputs
|
||||
TIntermAggregate* compoundStatement = intermediate.makeAggregate(sizeQueryAssign, loc);
|
||||
// Index of first output parameter
|
||||
const int outParamBase = mipQuery ? 2 : 1;
|
||||
|
||||
for (int compNum = 0; compNum < numDims; ++compNum) {
|
||||
TIntermTyped* indexedOut = nullptr;
|
||||
|
||||
if (numDims > 1) {
|
||||
TIntermTyped* component = intermediate.addConstantUnion(compNum, loc, true);
|
||||
indexedOut = intermediate.addIndex(EOpIndexDirect, sizeQueryReturn, component, loc);
|
||||
indexedOut->setType(TType(EbtUint, EvqTemporary, 1));
|
||||
indexedOut->setLoc(loc);
|
||||
} else {
|
||||
indexedOut = sizeQueryReturn;
|
||||
}
|
||||
|
||||
TIntermTyped* outParam = argAggregate->getSequence()[outParamBase + compNum]->getAsTyped();
|
||||
TIntermTyped* compAssign = intermediate.addAssign(EOpAssign, outParam, indexedOut, loc);
|
||||
|
||||
compoundStatement = intermediate.growAggregate(compoundStatement, compAssign);
|
||||
}
|
||||
|
||||
// handle mip level parameter
|
||||
if (mipQuery) {
|
||||
TIntermTyped* outParam = argAggregate->getSequence()[outParamBase + numDims]->getAsTyped();
|
||||
|
||||
TIntermAggregate* levelsQuery = new TIntermAggregate(EOpTextureQueryLevels);
|
||||
levelsQuery->getSequence().push_back(argTex);
|
||||
levelsQuery->setType(TType(EbtUint, EvqTemporary, 1));
|
||||
levelsQuery->setLoc(loc);
|
||||
|
||||
TIntermTyped* compAssign = intermediate.addAssign(EOpAssign, outParam, levelsQuery, loc);
|
||||
compoundStatement = intermediate.growAggregate(compoundStatement, compAssign);
|
||||
}
|
||||
|
||||
compoundStatement->setOperator(EOpSequence);
|
||||
compoundStatement->setLoc(loc);
|
||||
compoundStatement->setType(TType(EbtVoid));
|
||||
|
||||
node = compoundStatement;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break; // most pass through unchanged
|
||||
}
|
||||
|
||||
@@ -272,6 +272,18 @@ inline const char* FindEndOfArg(const char* arg)
|
||||
return *arg == '\0' ? nullptr : arg;
|
||||
}
|
||||
|
||||
// If this is a fixed vector size, such as V3, return the size. Else return 0.
|
||||
int FixedVecSize(const char* arg)
|
||||
{
|
||||
while (!IsEndOfArg(arg)) {
|
||||
if (isdigit(*arg))
|
||||
return *arg - '0';
|
||||
++arg;
|
||||
}
|
||||
|
||||
return 0; // none found.
|
||||
}
|
||||
|
||||
|
||||
// Return pointer to beginning of Nth argument specifier in the string.
|
||||
inline const char* NthArg(const char* arg, int n)
|
||||
@@ -571,6 +583,61 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c
|
||||
// { "Load", /* +sampleidex*/ "V4", nullptr, "@V,V,S", "FIU,I,I", EShLangFragmentMask },
|
||||
// { "Load", /* +samplindex, offset*/ "V4", nullptr, "@V,V,S,V", "FIU,I,I,I", EShLangFragmentMask },
|
||||
|
||||
// table of overloads from: https://msdn.microsoft.com/en-us/library/windows/desktop/bb509693(v=vs.85).aspx
|
||||
//
|
||||
// UINT Width
|
||||
// UINT MipLevel, UINT Width, UINT NumberOfLevels
|
||||
{ "GetDimensions", /* 1D */ "-", "-", "%V1,>S", "FUI,U", EShLangAll },
|
||||
{ "GetDimensions", /* 1D */ "-", "-", "%V1,>S", "FUI,F", EShLangAll },
|
||||
{ "GetDimensions", /* 1D */ "-", "-", "%V1,S,>S,>S", "FUI,U,U,U", EShLangAll },
|
||||
{ "GetDimensions", /* 1D */ "-", "-", "%V1,S,>S,>S", "FUI,U,F,F", EShLangAll },
|
||||
|
||||
// UINT Width, UINT Elements
|
||||
// UINT MipLevel, UINT Width, UINT Elements, UINT NumberOfLevels
|
||||
{ "GetDimensions", /* 1DArray */ "-", "-", "@V1,>S,>S", "FUI,U,U", EShLangAll },
|
||||
{ "GetDimensions", /* 1DArray */ "-", "-", "@V1,>S,>S", "FUI,F,F", EShLangAll },
|
||||
{ "GetDimensions", /* 1DArray */ "-", "-", "@V1,S,>S,>S,>S", "FUI,U,U,U,U", EShLangAll },
|
||||
{ "GetDimensions", /* 1DArray */ "-", "-", "@V1,S,>S,>S,>S", "FUI,U,F,F,F", EShLangAll },
|
||||
|
||||
// UINT Width, UINT Height
|
||||
// UINT MipLevel, UINT Width, UINT Height, UINT NumberOfLevels
|
||||
{ "GetDimensions", /* 2D */ "-", "-", "%V2,>S,>S", "FUI,U,U", EShLangAll },
|
||||
{ "GetDimensions", /* 2D */ "-", "-", "%V2,>S,>S", "FUI,F,F", EShLangAll },
|
||||
{ "GetDimensions", /* 2D */ "-", "-", "%V2,S,>S,>S,>S", "FUI,U,U,U,U", EShLangAll },
|
||||
{ "GetDimensions", /* 2D */ "-", "-", "%V2,S,>S,>S,>S", "FUI,U,F,F,F", EShLangAll },
|
||||
|
||||
// UINT Width, UINT Height, UINT Elements
|
||||
// UINT MipLevel, UINT Width, UINT Height, UINT Elements, UINT NumberOfLevels
|
||||
{ "GetDimensions", /* 2DArray */ "-", "-", "@V2,>S,>S,>S", "FUI,U,U,U", EShLangAll },
|
||||
{ "GetDimensions", /* 2DArray */ "-", "-", "@V2,>S,>S,>S", "FUI,F,F,F", EShLangAll },
|
||||
{ "GetDimensions", /* 2DArray */ "-", "-", "@V2,S,>S,>S,>S,>S", "FUI,U,U,U,U,U", EShLangAll },
|
||||
{ "GetDimensions", /* 2DArray */ "-", "-", "@V2,S,>S,>S,>S,>S", "FUI,U,F,F,F,F", EShLangAll },
|
||||
|
||||
// UINT Width, UINT Height, UINT Depth
|
||||
// UINT MipLevel, UINT Width, UINT Height, UINT Depth, UINT NumberOfLevels
|
||||
{ "GetDimensions", /* 3D */ "-", "-", "%V3,>S,>S,>S", "FUI,U,U,U", EShLangAll },
|
||||
{ "GetDimensions", /* 3D */ "-", "-", "%V3,>S,>S,>S", "FUI,F,F,F", EShLangAll },
|
||||
{ "GetDimensions", /* 3D */ "-", "-", "%V3,S,>S,>S,>S,>S", "FUI,U,U,U,U,U", EShLangAll },
|
||||
{ "GetDimensions", /* 3D */ "-", "-", "%V3,S,>S,>S,>S,>S", "FUI,U,F,F,F,F", EShLangAll },
|
||||
|
||||
// UINT Width, UINT Height
|
||||
// UINT MipLevel, UINT Width, UINT Height, UINT NumberOfLevels
|
||||
{ "GetDimensions", /* Cube */ "-", "-", "%V4,>S,>S", "FUI,U,U", EShLangAll },
|
||||
{ "GetDimensions", /* Cube */ "-", "-", "%V4,>S,>S", "FUI,F,F", EShLangAll },
|
||||
{ "GetDimensions", /* Cube */ "-", "-", "%V4,S,>S,>S,>S", "FUI,U,U,U,U", EShLangAll },
|
||||
{ "GetDimensions", /* Cube */ "-", "-", "%V4,S,>S,>S,>S", "FUI,U,F,F,F", EShLangAll },
|
||||
|
||||
// UINT Width, UINT Height, UINT Elements
|
||||
// UINT MipLevel, UINT Width, UINT Height, UINT Elements, UINT NumberOfLevels
|
||||
{ "GetDimensions", /* CubeArray */ "-", "-", "@V4,>S,>S,>S", "FUI,U,U,U", EShLangAll },
|
||||
{ "GetDimensions", /* CubeArray */ "-", "-", "@V4,>S,>S,>S", "FUI,F,F,F", EShLangAll },
|
||||
{ "GetDimensions", /* CubeArray */ "-", "-", "@V4,S,>S,>S,>S,>S", "FUI,U,U,U,U,U", EShLangAll },
|
||||
{ "GetDimensions", /* CubeArray */ "-", "-", "@V4,S,>S,>S,>S,>S", "FUI,U,F,F,F,F", EShLangAll },
|
||||
|
||||
// TODO: GetDimensions for Texture2DMS, Texture2DMSArray
|
||||
// UINT Width, UINT Height, UINT Samples
|
||||
// UINT Width, UINT Height, UINT Elements, UINT Samples
|
||||
|
||||
// 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 },
|
||||
};
|
||||
@@ -593,7 +660,7 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c
|
||||
for (const char* argOrder = intrinsic.argOrder; !IsEndOfArg(argOrder); ++argOrder) { // for each order...
|
||||
const bool isTexture = IsTextureType(*argOrder);
|
||||
const bool isArrayed = IsTextureArrayed(*argOrder);
|
||||
const int fixedVecSize = isdigit(argOrder[1]) ? (argOrder[1] - '0') : 0;
|
||||
const int fixedVecSize = FixedVecSize(argOrder);
|
||||
|
||||
// calculate min and max vector and matrix dimensions
|
||||
int dim0Min = 1;
|
||||
@@ -663,7 +730,10 @@ void TBuiltInParseablesHlsl::initialize(int /*version*/, EProfile /*profile*/, c
|
||||
}
|
||||
}
|
||||
|
||||
if (fixedVecSize > 0 || isTexture) // skip over special characters
|
||||
// skip over special characters
|
||||
if (isTexture)
|
||||
++argOrder;
|
||||
if (isdigit(argOrder[1]))
|
||||
++argOrder;
|
||||
}
|
||||
|
||||
@@ -851,6 +921,7 @@ void TBuiltInParseablesHlsl::identifyBuiltIns(int /*version*/, EProfile /*profil
|
||||
symbolTable.relateToOperator("SampleGrad", EOpMethodSampleGrad);
|
||||
// symbolTable.relateToOperator("SampleLevel", EOpMethodSampleLevel);
|
||||
// symbolTable.relateToOperator("Load", EOpMethodLoad);
|
||||
symbolTable.relateToOperator("GetDimensions", EOpMethodGetDimensions);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user