HLSL: Add tx.GetDimensions method (uint returns only)

This commit is contained in:
LoopDawg
2016-07-15 11:22:24 -06:00
parent e4821e43c8
commit 5d58faecc0
9 changed files with 3199 additions and 7 deletions

View File

@@ -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:

View File

@@ -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
}

View File

@@ -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);
}
//