Merge pull request #121 from amdrexu/feature
Parser & SPV: Implement two extensions regarding GLSL sparse texture.
This commit is contained in:
@@ -1884,6 +1884,14 @@ void TGlslangToSpvTraverser::handleFunctionEntry(const glslang::TIntermAggregate
|
||||
void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& node, std::vector<spv::Id>& arguments)
|
||||
{
|
||||
const glslang::TIntermSequence& glslangArguments = node.getSequence();
|
||||
|
||||
glslang::TSampler sampler = {};
|
||||
bool cubeCompare = false;
|
||||
if (node.isTexture()) {
|
||||
sampler = glslangArguments[0]->getAsTyped()->getType().getSampler();
|
||||
cubeCompare = sampler.dim == glslang::EsdCube && sampler.arrayed && sampler.shadow;
|
||||
}
|
||||
|
||||
for (int i = 0; i < (int)glslangArguments.size(); ++i) {
|
||||
builder.clearAccessChain();
|
||||
glslangArguments[i]->traverse(this);
|
||||
@@ -1902,6 +1910,51 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate&
|
||||
if (i == 0)
|
||||
lvalue = true;
|
||||
break;
|
||||
case glslang::EOpSparseTexture:
|
||||
if ((cubeCompare && i == 3) || (! cubeCompare && i == 2))
|
||||
lvalue = true;
|
||||
break;
|
||||
case glslang::EOpSparseTextureClamp:
|
||||
if ((cubeCompare && i == 4) || (! cubeCompare && i == 3))
|
||||
lvalue = true;
|
||||
break;
|
||||
case glslang::EOpSparseTextureLod:
|
||||
case glslang::EOpSparseTextureOffset:
|
||||
if (i == 3)
|
||||
lvalue = true;
|
||||
break;
|
||||
case glslang::EOpSparseTextureFetch:
|
||||
if ((sampler.dim != glslang::EsdRect && i == 3) || (sampler.dim == glslang::EsdRect && i == 2))
|
||||
lvalue = true;
|
||||
break;
|
||||
case glslang::EOpSparseTextureFetchOffset:
|
||||
if ((sampler.dim != glslang::EsdRect && i == 4) || (sampler.dim == glslang::EsdRect && i == 3))
|
||||
lvalue = true;
|
||||
break;
|
||||
case glslang::EOpSparseTextureLodOffset:
|
||||
case glslang::EOpSparseTextureGrad:
|
||||
case glslang::EOpSparseTextureOffsetClamp:
|
||||
if (i == 4)
|
||||
lvalue = true;
|
||||
break;
|
||||
case glslang::EOpSparseTextureGradOffset:
|
||||
case glslang::EOpSparseTextureGradClamp:
|
||||
if (i == 5)
|
||||
lvalue = true;
|
||||
break;
|
||||
case glslang::EOpSparseTextureGradOffsetClamp:
|
||||
if (i == 6)
|
||||
lvalue = true;
|
||||
break;
|
||||
case glslang::EOpSparseTextureGather:
|
||||
if ((sampler.shadow && i == 3) || (! sampler.shadow && i == 2))
|
||||
lvalue = true;
|
||||
break;
|
||||
case glslang::EOpSparseTextureGatherOffset:
|
||||
case glslang::EOpSparseTextureGatherOffsets:
|
||||
if ((sampler.shadow && i == 4) || (! sampler.shadow && i == 3))
|
||||
lvalue = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1963,6 +2016,8 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
||||
return builder.createTextureQueryCall(spv::OpImageQueryLod, params);
|
||||
case glslang::EOpTextureQueryLevels:
|
||||
return builder.createTextureQueryCall(spv::OpImageQueryLevels, params);
|
||||
case glslang::EOpSparseTexelsResident:
|
||||
return builder.createUnaryOp(spv::OpImageSparseTexelsResident, builder.makeBoolType(), arguments[0]);
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
@@ -1990,7 +2045,11 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
||||
operands.push_back(*opIt);
|
||||
builder.createNoResultOp(spv::OpImageWrite, operands);
|
||||
return spv::NoResult;
|
||||
} else {
|
||||
} else if (node->isSparseImage()) {
|
||||
spv::MissingFunctionality("sparse image functions");
|
||||
return spv::NoResult;
|
||||
}
|
||||
else {
|
||||
// Process image atomic operations
|
||||
|
||||
// GLSL "IMAGE_PARAMS" will involve in constructing an image texel pointer and this pointer,
|
||||
@@ -2010,7 +2069,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
||||
}
|
||||
|
||||
// Check for texture functions other than queries
|
||||
|
||||
bool sparse = node->isSparseTexture();
|
||||
bool cubeCompare = sampler.dim == glslang::EsdCube && sampler.arrayed && sampler.shadow;
|
||||
|
||||
// check for bias argument
|
||||
@@ -2021,6 +2080,10 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
||||
++nonBiasArgCount;
|
||||
if (cracked.grad)
|
||||
nonBiasArgCount += 2;
|
||||
if (cracked.lodClamp)
|
||||
++nonBiasArgCount;
|
||||
if (sparse)
|
||||
++nonBiasArgCount;
|
||||
|
||||
if ((int)arguments.size() > nonBiasArgCount)
|
||||
bias = true;
|
||||
@@ -2032,9 +2095,10 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
||||
int extraArgs = 0;
|
||||
|
||||
// sort out where Dref is coming from
|
||||
if (sampler.shadow && sampler.dim == glslang::EsdCube && sampler.arrayed)
|
||||
if (cubeCompare) {
|
||||
params.Dref = arguments[2];
|
||||
else if (sampler.shadow && cracked.gather) {
|
||||
++extraArgs;
|
||||
} else if (sampler.shadow && cracked.gather) {
|
||||
params.Dref = arguments[2];
|
||||
++extraArgs;
|
||||
} else if (sampler.shadow) {
|
||||
@@ -2066,6 +2130,14 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
||||
params.offsets = arguments[2 + extraArgs];
|
||||
++extraArgs;
|
||||
}
|
||||
if (cracked.lodClamp) {
|
||||
params.lodClamp = arguments[2 + extraArgs];
|
||||
++extraArgs;
|
||||
}
|
||||
if (sparse) {
|
||||
params.texelOut = arguments[2 + extraArgs];
|
||||
++extraArgs;
|
||||
}
|
||||
if (bias) {
|
||||
params.bias = arguments[2 + extraArgs];
|
||||
++extraArgs;
|
||||
@@ -2080,7 +2152,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
||||
}
|
||||
}
|
||||
|
||||
return builder.createTextureCall(precision, convertGlslangToSpvType(node->getType()), cracked.fetch, cracked.proj, cracked.gather, params);
|
||||
return builder.createTextureCall(precision, convertGlslangToSpvType(node->getType()), sparse, cracked.fetch, cracked.proj, cracked.gather, params);
|
||||
}
|
||||
|
||||
spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAggregate* node)
|
||||
|
||||
@@ -1222,7 +1222,7 @@ Id Builder::createBuiltinCall(Decoration /*precision*/, Id resultType, Id builti
|
||||
|
||||
// Accept all parameters needed to create a texture instruction.
|
||||
// Create the correct instruction based on the inputs, and make the call.
|
||||
Id Builder::createTextureCall(Decoration precision, Id resultType, bool fetch, bool proj, bool gather, const TextureParameters& parameters)
|
||||
Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, bool gather, const TextureParameters& parameters)
|
||||
{
|
||||
static const int maxTextureArgs = 10;
|
||||
Id texArgs[maxTextureArgs] = {};
|
||||
@@ -1275,6 +1275,10 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool fetch, b
|
||||
mask = (ImageOperandsMask)(mask | ImageOperandsSampleMask);
|
||||
texArgs[numArgs++] = parameters.sample;
|
||||
}
|
||||
if (parameters.lodClamp) {
|
||||
mask = (ImageOperandsMask)(mask | ImageOperandsMinLodMask);
|
||||
texArgs[numArgs++] = parameters.lodClamp;
|
||||
}
|
||||
if (mask == ImageOperandsMaskNone)
|
||||
--numArgs; // undo speculative reservation for the mask argument
|
||||
else
|
||||
@@ -1286,35 +1290,68 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool fetch, b
|
||||
Op opCode;
|
||||
opCode = OpImageSampleImplicitLod;
|
||||
if (fetch) {
|
||||
opCode = OpImageFetch;
|
||||
if (sparse)
|
||||
opCode = OpImageSparseFetch;
|
||||
else
|
||||
opCode = OpImageFetch;
|
||||
} else if (gather) {
|
||||
if (parameters.Dref)
|
||||
opCode = OpImageDrefGather;
|
||||
if (sparse)
|
||||
opCode = OpImageSparseDrefGather;
|
||||
else
|
||||
opCode = OpImageDrefGather;
|
||||
else
|
||||
opCode = OpImageGather;
|
||||
if (sparse)
|
||||
opCode = OpImageSparseGather;
|
||||
else
|
||||
opCode = OpImageGather;
|
||||
} else if (xplicit) {
|
||||
if (parameters.Dref) {
|
||||
if (proj)
|
||||
opCode = OpImageSampleProjDrefExplicitLod;
|
||||
if (sparse)
|
||||
opCode = OpImageSparseSampleProjDrefExplicitLod;
|
||||
else
|
||||
opCode = OpImageSampleProjDrefExplicitLod;
|
||||
else
|
||||
opCode = OpImageSampleDrefExplicitLod;
|
||||
if (sparse)
|
||||
opCode = OpImageSparseSampleDrefExplicitLod;
|
||||
else
|
||||
opCode = OpImageSampleDrefExplicitLod;
|
||||
} else {
|
||||
if (proj)
|
||||
opCode = OpImageSampleProjExplicitLod;
|
||||
if (sparse)
|
||||
opCode = OpImageSparseSampleProjExplicitLod;
|
||||
else
|
||||
opCode = OpImageSampleProjExplicitLod;
|
||||
else
|
||||
opCode = OpImageSampleExplicitLod;
|
||||
if (sparse)
|
||||
opCode = OpImageSparseSampleExplicitLod;
|
||||
else
|
||||
opCode = OpImageSampleExplicitLod;
|
||||
}
|
||||
} else {
|
||||
if (parameters.Dref) {
|
||||
if (proj)
|
||||
opCode = OpImageSampleProjDrefImplicitLod;
|
||||
if (sparse)
|
||||
opCode = OpImageSparseSampleProjDrefImplicitLod;
|
||||
else
|
||||
opCode = OpImageSampleProjDrefImplicitLod;
|
||||
else
|
||||
opCode = OpImageSampleDrefImplicitLod;
|
||||
if (sparse)
|
||||
opCode = OpImageSparseSampleDrefImplicitLod;
|
||||
else
|
||||
opCode = OpImageSampleDrefImplicitLod;
|
||||
} else {
|
||||
if (proj)
|
||||
opCode = OpImageSampleProjImplicitLod;
|
||||
if (sparse)
|
||||
opCode = OpImageSparseSampleProjImplicitLod;
|
||||
else
|
||||
opCode = OpImageSampleProjImplicitLod;
|
||||
else
|
||||
opCode = OpImageSampleImplicitLod;
|
||||
if (sparse)
|
||||
opCode = OpImageSparseSampleImplicitLod;
|
||||
else
|
||||
opCode = OpImageSampleImplicitLod;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1335,6 +1372,15 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool fetch, b
|
||||
}
|
||||
}
|
||||
|
||||
Id typeId0 = 0;
|
||||
Id typeId1 = 0;
|
||||
|
||||
if (sparse) {
|
||||
typeId0 = resultType;
|
||||
typeId1 = getDerefTypeId(parameters.texelOut);
|
||||
resultType = makeStructResultType(typeId0, typeId1);
|
||||
}
|
||||
|
||||
// Build the SPIR-V instruction
|
||||
Instruction* textureInst = new Instruction(getUniqueId(), resultType, opCode);
|
||||
for (int op = 0; op < optArgNum; ++op)
|
||||
@@ -1348,10 +1394,16 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool fetch, b
|
||||
|
||||
Id resultId = textureInst->getResultId();
|
||||
|
||||
// When a smear is needed, do it, as per what was computed
|
||||
// above when resultType was changed to a scalar type.
|
||||
if (resultType != smearedType)
|
||||
resultId = smearScalar(precision, resultId, smearedType);
|
||||
if (sparse) {
|
||||
// Decode the return type that was a special structure
|
||||
createStore(createCompositeExtract(resultId, typeId1, 1), parameters.texelOut);
|
||||
resultId = createCompositeExtract(resultId, typeId0, 0);
|
||||
} else {
|
||||
// When a smear is needed, do it, as per what was computed
|
||||
// above when resultType was changed to a scalar type.
|
||||
if (resultType != smearedType)
|
||||
resultId = smearScalar(precision, resultId, smearedType);
|
||||
}
|
||||
|
||||
return resultId;
|
||||
}
|
||||
|
||||
@@ -310,10 +310,12 @@ public:
|
||||
Id gradY;
|
||||
Id sample;
|
||||
Id comp;
|
||||
Id texelOut;
|
||||
Id lodClamp;
|
||||
};
|
||||
|
||||
// Select the correct texture operation based on all inputs, and emit the correct instruction
|
||||
Id createTextureCall(Decoration precision, Id resultType, bool fetch, bool proj, bool gather, const TextureParameters&);
|
||||
Id createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, bool gather, const TextureParameters&);
|
||||
|
||||
// Emit the OpTextureQuery* instruction that was passed in.
|
||||
// Figure out the right return value and type, and return it.
|
||||
|
||||
Reference in New Issue
Block a user