|
@@ -549,8 +549,7 @@ SPIRVEmitter::SPIRVEmitter(CompilerInstance &ci)
|
|
|
declIdMapper(shaderModel, astContext, spvContext, spvBuilder, *this,
|
|
|
featureManager, spirvOptions),
|
|
|
entryFunction(nullptr), curFunction(nullptr), curThis(nullptr),
|
|
|
- seenPushConstantAt(), isSpecConstantMode(false),
|
|
|
- foundNonUniformResourceIndex(false), needsLegalization(false),
|
|
|
+ seenPushConstantAt(), isSpecConstantMode(false), needsLegalization(false),
|
|
|
mainSourceFile(nullptr) {
|
|
|
if (shaderModel.GetKind() == hlsl::ShaderModel::Kind::Invalid)
|
|
|
emitError("unknown shader module: %0", {}) << shaderModel.GetName();
|
|
@@ -903,12 +902,6 @@ SpirvInstruction *SPIRVEmitter::loadIfGLValue(const Expr *expr,
|
|
|
}
|
|
|
assert(loadedInstr);
|
|
|
|
|
|
- // Decorate with NonUniformEXT if loading from a pointer with that property.
|
|
|
- // We are likely loading an element from the resource array here.
|
|
|
- if (info->isNonUniform()) {
|
|
|
- spvBuilder.decorateNonUniformEXT(loadedInstr);
|
|
|
- }
|
|
|
-
|
|
|
// Special-case: According to the SPIR-V Spec: There is no physical size or
|
|
|
// bit pattern defined for boolean type. Therefore an unsigned integer is used
|
|
|
// to represent booleans when layout is required. In such cases, after loading
|
|
@@ -1946,19 +1939,11 @@ void SPIRVEmitter::doSwitchStmt(const SwitchStmt *switchStmt,
|
|
|
|
|
|
SpirvInstruction *
|
|
|
SPIRVEmitter::doArraySubscriptExpr(const ArraySubscriptExpr *expr) {
|
|
|
- // Make sure we don't have previously unhandled NonUniformResourceIndex()
|
|
|
- assert(!foundNonUniformResourceIndex);
|
|
|
-
|
|
|
llvm::SmallVector<SpirvInstruction *, 4> indices;
|
|
|
const auto *base = collectArrayStructIndices(
|
|
|
expr, /*rawIndex*/ false, /*rawIndices*/ nullptr, &indices);
|
|
|
auto *info = loadIfAliasVarRef(base);
|
|
|
|
|
|
- if (foundNonUniformResourceIndex) {
|
|
|
- info->setNonUniform(); // Carry forward the NonUniformEXT decoration
|
|
|
- foundNonUniformResourceIndex = false;
|
|
|
- }
|
|
|
-
|
|
|
if (!indices.empty()) {
|
|
|
info = turnIntoElementPtr(base->getType(), info, expr->getType(), indices);
|
|
|
}
|
|
@@ -3004,14 +2989,8 @@ SPIRVEmitter::processTextureLevelOfDetail(const CXXMemberCallExpr *expr,
|
|
|
auto *samplerState = doExpr(expr->getArg(0));
|
|
|
auto *coordinate = doExpr(expr->getArg(1));
|
|
|
|
|
|
- auto *sampledImage = spvBuilder.createBinaryOp(
|
|
|
- spv::Op::OpSampledImage, object->getType(), objectInfo, samplerState);
|
|
|
-
|
|
|
- if (objectInfo->isNonUniform() || samplerState->isNonUniform()) {
|
|
|
- // The sampled image will be used to access resource's memory, so we need
|
|
|
- // to decorate it with NonUniformEXT.
|
|
|
- spvBuilder.decorateNonUniformEXT(sampledImage);
|
|
|
- }
|
|
|
+ auto *sampledImage = spvBuilder.createSampledImage(
|
|
|
+ object->getType(), objectInfo, samplerState, expr->getExprLoc());
|
|
|
|
|
|
// The result type of OpImageQueryLod must be a float2.
|
|
|
const QualType queryResultType =
|
|
@@ -3100,7 +3079,6 @@ SpirvInstruction *SPIRVEmitter::processTextureGatherRGBACmpRGBA(
|
|
|
}
|
|
|
|
|
|
auto *status = hasStatusArg ? doExpr(expr->getArg(numArgs - 1)) : nullptr;
|
|
|
- const bool isNonUniform = image->isNonUniform() || sampler->isNonUniform();
|
|
|
|
|
|
if (needsEmulation) {
|
|
|
const auto elemType = hlsl::GetHLSLVecElementType(callee->getReturnType());
|
|
@@ -3109,7 +3087,7 @@ SpirvInstruction *SPIRVEmitter::processTextureGatherRGBACmpRGBA(
|
|
|
for (uint32_t i = 0; i < 4; ++i) {
|
|
|
varOffset = doExpr(expr->getArg(2 + isCmp + i));
|
|
|
auto *gatherRet = spvBuilder.createImageGather(
|
|
|
- retType, imageType, image, sampler, isNonUniform, coordinate,
|
|
|
+ retType, imageType, image, sampler, coordinate,
|
|
|
spvBuilder.getConstantInt(astContext.IntTy,
|
|
|
llvm::APInt(32, component, true)),
|
|
|
compareVal,
|
|
@@ -3122,7 +3100,7 @@ SpirvInstruction *SPIRVEmitter::processTextureGatherRGBACmpRGBA(
|
|
|
}
|
|
|
|
|
|
return spvBuilder.createImageGather(
|
|
|
- retType, imageType, image, sampler, isNonUniform, coordinate,
|
|
|
+ retType, imageType, image, sampler, coordinate,
|
|
|
spvBuilder.getConstantInt(astContext.IntTy,
|
|
|
llvm::APInt(32, component, true)),
|
|
|
compareVal, constOffset, varOffset, constOffsets,
|
|
@@ -3173,8 +3151,7 @@ SPIRVEmitter::processTextureGatherCmp(const CXXMemberCallExpr *expr) {
|
|
|
hasStatusArg ? doExpr(expr->getArg(numArgs - 1)) : nullptr;
|
|
|
|
|
|
return spvBuilder.createImageGather(
|
|
|
- retType, imageType, image, sampler,
|
|
|
- image->isNonUniform() || sampler->isNonUniform(), coordinate,
|
|
|
+ retType, imageType, image, sampler, coordinate,
|
|
|
/*component*/ nullptr, comparator, constOffset, varOffset,
|
|
|
/*constOffsets*/ nullptr,
|
|
|
/*sampleNumber*/ nullptr, status);
|
|
@@ -3197,11 +3174,6 @@ SpirvInstruction *SPIRVEmitter::processBufferTextureLoad(
|
|
|
|
|
|
auto *objectInfo = loadIfGLValue(object);
|
|
|
|
|
|
- if (objectInfo->isNonUniform()) {
|
|
|
- // Decoreate the image handle for OpImageFetch/OpImageRead
|
|
|
- spvBuilder.decorateNonUniformEXT(objectInfo);
|
|
|
- }
|
|
|
-
|
|
|
// For Texture2DMS and Texture2DMSArray, Sample must be used rather than Lod.
|
|
|
SpirvInstruction *sampleNumber = nullptr;
|
|
|
if (TypeTranslator::isTextureMS(type) ||
|
|
@@ -3966,7 +3938,7 @@ SPIRVEmitter::processIntrinsicMemberCall(const CXXMemberCallExpr *expr,
|
|
|
|
|
|
SpirvInstruction *SPIRVEmitter::createImageSample(
|
|
|
QualType retType, QualType imageType, SpirvInstruction *image,
|
|
|
- SpirvInstruction *sampler, bool isNonUniform, SpirvInstruction *coordinate,
|
|
|
+ SpirvInstruction *sampler, SpirvInstruction *coordinate,
|
|
|
SpirvInstruction *compareVal, SpirvInstruction *bias, SpirvInstruction *lod,
|
|
|
std::pair<SpirvInstruction *, SpirvInstruction *> grad,
|
|
|
SpirvInstruction *constOffset, SpirvInstruction *varOffset,
|
|
@@ -3976,10 +3948,10 @@ SpirvInstruction *SPIRVEmitter::createImageSample(
|
|
|
// SampleDref* instructions in SPIR-V always return a scalar.
|
|
|
// They also have the correct type in HLSL.
|
|
|
if (compareVal) {
|
|
|
- return spvBuilder.createImageSample(
|
|
|
- retType, imageType, image, sampler, isNonUniform, coordinate,
|
|
|
- compareVal, bias, lod, grad, constOffset, varOffset, constOffsets,
|
|
|
- sample, minLod, residencyCodeId);
|
|
|
+ return spvBuilder.createImageSample(retType, imageType, image, sampler,
|
|
|
+ coordinate, compareVal, bias, lod, grad,
|
|
|
+ constOffset, varOffset, constOffsets,
|
|
|
+ sample, minLod, residencyCodeId);
|
|
|
}
|
|
|
|
|
|
// Non-Dref Sample instructions in SPIR-V must always return a vec4.
|
|
@@ -4003,9 +3975,9 @@ SpirvInstruction *SPIRVEmitter::createImageSample(
|
|
|
needsLegalization = true;
|
|
|
|
|
|
auto *retVal = spvBuilder.createImageSample(
|
|
|
- texelType, imageType, image, sampler, isNonUniform, coordinate,
|
|
|
- compareVal, bias, lod, grad, constOffset, varOffset, constOffsets, sample,
|
|
|
- minLod, residencyCodeId);
|
|
|
+ texelType, imageType, image, sampler, coordinate, compareVal, bias, lod,
|
|
|
+ grad, constOffset, varOffset, constOffsets, sample, minLod,
|
|
|
+ residencyCodeId);
|
|
|
|
|
|
// Extract smaller vector from the vec4 result if necessary.
|
|
|
if (texelType != retType) {
|
|
@@ -4071,19 +4043,18 @@ SPIRVEmitter::processTextureSampleGather(const CXXMemberCallExpr *expr,
|
|
|
SpirvInstruction *constOffset = nullptr, *varOffset = nullptr;
|
|
|
if (hasOffsetArg)
|
|
|
handleOffsetInMethodCall(expr, 2, &constOffset, &varOffset);
|
|
|
- const bool isNonUniform = image->isNonUniform() || sampler->isNonUniform();
|
|
|
|
|
|
const auto retType = expr->getDirectCallee()->getReturnType();
|
|
|
if (isSample) {
|
|
|
- return createImageSample(
|
|
|
- retType, imageType, image, sampler, isNonUniform, coordinate,
|
|
|
- /*compareVal*/ nullptr, /*bias*/ nullptr, /*lod*/ nullptr,
|
|
|
- std::make_pair(nullptr, nullptr), constOffset, varOffset,
|
|
|
- /*constOffsets*/ nullptr, /*sampleNumber*/ nullptr,
|
|
|
- /*minLod*/ clamp, status);
|
|
|
+ return createImageSample(retType, imageType, image, sampler, coordinate,
|
|
|
+ /*compareVal*/ nullptr, /*bias*/ nullptr,
|
|
|
+ /*lod*/ nullptr, std::make_pair(nullptr, nullptr),
|
|
|
+ constOffset, varOffset,
|
|
|
+ /*constOffsets*/ nullptr, /*sampleNumber*/ nullptr,
|
|
|
+ /*minLod*/ clamp, status);
|
|
|
} else {
|
|
|
return spvBuilder.createImageGather(
|
|
|
- retType, imageType, image, sampler, isNonUniform, coordinate,
|
|
|
+ retType, imageType, image, sampler, coordinate,
|
|
|
// .Gather() doc says we return four components of red data.
|
|
|
spvBuilder.getConstantInt(astContext.IntTy, llvm::APInt(32, 0)),
|
|
|
/*compareVal*/ nullptr, constOffset, varOffset,
|
|
@@ -4161,13 +4132,12 @@ SPIRVEmitter::processTextureSampleBiasLevel(const CXXMemberCallExpr *expr,
|
|
|
|
|
|
const auto retType = expr->getDirectCallee()->getReturnType();
|
|
|
|
|
|
- return createImageSample(
|
|
|
- retType, imageType, image, sampler,
|
|
|
- image->isNonUniform() || sampler->isNonUniform(), coordinate,
|
|
|
- /*compareVal*/ nullptr, bias, lod, std::make_pair(nullptr, nullptr),
|
|
|
- constOffset, varOffset,
|
|
|
- /*constOffsets*/ nullptr, /*sampleNumber*/ nullptr, /*minLod*/ clamp,
|
|
|
- status);
|
|
|
+ return createImageSample(retType, imageType, image, sampler, coordinate,
|
|
|
+ /*compareVal*/ nullptr, bias, lod,
|
|
|
+ std::make_pair(nullptr, nullptr), constOffset,
|
|
|
+ varOffset,
|
|
|
+ /*constOffsets*/ nullptr, /*sampleNumber*/ nullptr,
|
|
|
+ /*minLod*/ clamp, status);
|
|
|
}
|
|
|
|
|
|
SpirvInstruction *
|
|
@@ -4219,13 +4189,12 @@ SPIRVEmitter::processTextureSampleGrad(const CXXMemberCallExpr *expr) {
|
|
|
handleOffsetInMethodCall(expr, 4, &constOffset, &varOffset);
|
|
|
|
|
|
const auto retType = expr->getDirectCallee()->getReturnType();
|
|
|
- return createImageSample(
|
|
|
- retType, imageType, image, sampler,
|
|
|
- image->isNonUniform() || sampler->isNonUniform(), coordinate,
|
|
|
- /*compareVal*/ nullptr, /*bias*/ nullptr, /*lod*/ nullptr,
|
|
|
- std::make_pair(ddx, ddy), constOffset, varOffset,
|
|
|
- /*constOffsets*/ nullptr, /*sampleNumber*/ nullptr,
|
|
|
- /*minLod*/ clamp, status);
|
|
|
+ return createImageSample(retType, imageType, image, sampler, coordinate,
|
|
|
+ /*compareVal*/ nullptr, /*bias*/ nullptr,
|
|
|
+ /*lod*/ nullptr, std::make_pair(ddx, ddy),
|
|
|
+ constOffset, varOffset,
|
|
|
+ /*constOffsets*/ nullptr, /*sampleNumber*/ nullptr,
|
|
|
+ /*minLod*/ clamp, status);
|
|
|
}
|
|
|
|
|
|
SpirvInstruction *
|
|
@@ -4311,8 +4280,7 @@ SPIRVEmitter::processTextureSampleCmpCmpLevelZero(const CXXMemberCallExpr *expr,
|
|
|
const auto imageType = imageExpr->getType();
|
|
|
|
|
|
return createImageSample(
|
|
|
- retType, imageType, image, sampler,
|
|
|
- image->isNonUniform() || sampler->isNonUniform(), coordinate, compareVal,
|
|
|
+ retType, imageType, image, sampler, coordinate, compareVal,
|
|
|
/*bias*/ nullptr, lod, std::make_pair(nullptr, nullptr), constOffset,
|
|
|
varOffset,
|
|
|
/*constOffsets*/ nullptr, /*sampleNumber*/ nullptr, /*minLod*/ clamp,
|
|
@@ -5260,9 +5228,6 @@ SpirvInstruction *SPIRVEmitter::processBinaryOp(
|
|
|
// Propagate RelaxedPrecision
|
|
|
if (lhsVal->isRelaxedPrecision() || rhsVal->isRelaxedPrecision())
|
|
|
val->setRelaxedPrecision();
|
|
|
- // Propagate NonUniformEXT
|
|
|
- if (lhsVal->isNonUniform() || rhsVal->isNonUniform())
|
|
|
- val->setNonUniform();
|
|
|
|
|
|
return val;
|
|
|
}
|
|
@@ -5797,10 +5762,6 @@ SPIRVEmitter::tryToAssignToRWBufferRWTexture(const Expr *lhs,
|
|
|
auto *baseInfo = doExpr(baseExpr);
|
|
|
auto *image = spvBuilder.createLoad(imageType, baseInfo);
|
|
|
spvBuilder.createImageWrite(imageType, image, loc, rhs);
|
|
|
- if (baseInfo->isNonUniform()) {
|
|
|
- // Decorate the image handle for OpImageWrite
|
|
|
- spvBuilder.decorateNonUniformEXT(image);
|
|
|
- }
|
|
|
return rhs;
|
|
|
}
|
|
|
return nullptr;
|
|
@@ -6841,11 +6802,6 @@ SPIRVEmitter::processIntrinsicInterlockedMethod(const CallExpr *expr,
|
|
|
auto *coordInstr = doExpr(index);
|
|
|
ptr = spvBuilder.createImageTexelPointer(baseType, baseInstr, coordInstr,
|
|
|
zero);
|
|
|
- if (baseInstr->isNonUniform()) {
|
|
|
- // Image texel pointer will used to access image memory. Vulkan requires
|
|
|
- // it to be decorated with NonUniformEXT.
|
|
|
- spvBuilder.decorateNonUniformEXT(ptr);
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
if (!ptr) {
|
|
@@ -6902,10 +6858,7 @@ SPIRVEmitter::processIntrinsicInterlockedMethod(const CallExpr *expr,
|
|
|
|
|
|
SpirvInstruction *
|
|
|
SPIRVEmitter::processIntrinsicNonUniformResourceIndex(const CallExpr *expr) {
|
|
|
- foundNonUniformResourceIndex = true;
|
|
|
auto *index = doExpr(expr->getArg(0));
|
|
|
- index->setNonUniform();
|
|
|
-
|
|
|
// Decorate the expression in NonUniformResourceIndex() with NonUniformEXT.
|
|
|
// Aside from this, we also need to eventually populate the NonUniformEXT
|
|
|
// status to the usage of this expression: the "pointer" operand to a memory
|
|
@@ -6915,8 +6868,7 @@ SPIRVEmitter::processIntrinsicNonUniformResourceIndex(const CallExpr *expr) {
|
|
|
// image instructions) and the resource descriptor being accessed is not
|
|
|
// dynamically uniform, then the operand corresponding to that resource (e.g.
|
|
|
// the pointer or sampled image operand) must be decorated with NonUniformEXT.
|
|
|
- spvBuilder.decorateNonUniformEXT(index);
|
|
|
-
|
|
|
+ index->setNonUniform();
|
|
|
return index;
|
|
|
}
|
|
|
|
|
@@ -8901,7 +8853,7 @@ SpirvConstant *SPIRVEmitter::translateAPValue(const APValue &value,
|
|
|
|
|
|
SpirvConstant *SPIRVEmitter::translateAPInt(const llvm::APInt &intValue,
|
|
|
QualType targetType) {
|
|
|
- targetType = typeTranslator.getIntendedLiteralType(targetType);
|
|
|
+ targetType = typeTranslator.getIntendedLiteralType(targetType);
|
|
|
return spvBuilder.getConstantInt(targetType, intValue, isSpecConstantMode);
|
|
|
}
|
|
|
|
|
@@ -8974,7 +8926,7 @@ SPIRVEmitter::tryToEvaluateAsFloat32(const llvm::APFloat &floatValue) {
|
|
|
|
|
|
SpirvConstant *SPIRVEmitter::translateAPFloat(llvm::APFloat floatValue,
|
|
|
QualType targetType) {
|
|
|
- targetType = typeTranslator.getIntendedLiteralType(targetType);
|
|
|
+ targetType = typeTranslator.getIntendedLiteralType(targetType);
|
|
|
return spvBuilder.getConstantFloat(targetType, floatValue,
|
|
|
isSpecConstantMode);
|
|
|
}
|