From 5a0224a0773f6d7f5eae8515424af5fa8faa9c14 Mon Sep 17 00:00:00 2001 From: Yong He Date: Thu, 26 Sep 2024 09:44:08 -0700 Subject: Move texture format inference to frontend and add reflection api for it. (#5155) --- source/slang/slang-ir-resolve-texture-format.cpp | 142 +++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 source/slang/slang-ir-resolve-texture-format.cpp (limited to 'source/slang/slang-ir-resolve-texture-format.cpp') diff --git a/source/slang/slang-ir-resolve-texture-format.cpp b/source/slang/slang-ir-resolve-texture-format.cpp new file mode 100644 index 000000000..7cd81fc2d --- /dev/null +++ b/source/slang/slang-ir-resolve-texture-format.cpp @@ -0,0 +1,142 @@ +#include "slang-ir-resolve-texture-format.h" +#include "slang-ir-insts.h" +#include "slang-ir-clone.h" + +namespace Slang +{ + static IRType* replaceImageElementType(IRInst* originalType, IRInst* newElementType) + { + switch (originalType->getOp()) + { + case kIROp_ArrayType: + case kIROp_UnsizedArrayType: + case kIROp_PtrType: + case kIROp_OutType: + case kIROp_RefType: + case kIROp_ConstRefType: + case kIROp_InOutType: + { + auto newInnerType = replaceImageElementType(originalType->getOperand(0), newElementType); + if (newInnerType != originalType->getOperand(0)) + { + IRBuilder builder(originalType); + builder.setInsertBefore(originalType); + IRCloneEnv cloneEnv; + cloneEnv.mapOldValToNew.add(originalType->getOperand(0), newInnerType); + return (IRType*)cloneInst(&cloneEnv, &builder, originalType); + } + return (IRType*)originalType; + } + + default: + if (as(originalType)) + return (IRType*)newElementType; + return (IRType*)originalType; + } + } + + static void resolveTextureFormatForParameter(IRInst* textureInst, IRTextureTypeBase* textureType) + { + ImageFormat format = (ImageFormat)(textureType->getFormat()); + auto decor = textureInst->findDecoration(); + if (!decor) + return; + if (decor->getFormat() == (ImageFormat)textureType->getFormat()) + return; + + format = decor->getFormat(); + if (format != ImageFormat::unknown) + { + IRBuilder builder(textureInst->getModule()); + builder.setInsertBefore(textureInst); + auto formatArg = builder.getIntValue(builder.getUIntType(), IRIntegerValue(format)); + + auto newType = builder.getTextureType( + textureType->getElementType(), + textureType->getShapeInst(), + textureType->getIsArrayInst(), + textureType->getIsMultisampleInst(), + textureType->getSampleCountInst(), + textureType->getAccessInst(), + textureType->getIsShadowInst(), + textureType->getIsCombinedInst(), + formatArg); + + List typeReplacementWorkList; + HashSet typeReplacementWorkListSet; + + auto newInstType = (IRType*)replaceImageElementType(textureInst->getFullType(), newType); + textureInst->setFullType(newInstType); + + for (auto use = textureInst->firstUse; use; use = use->nextUse) + { + if (typeReplacementWorkListSet.add(use)) + typeReplacementWorkList.add(use); + } + + // Update the types on dependent insts. + for (Index i = 0; i < typeReplacementWorkList.getCount(); i++) + { + auto use = typeReplacementWorkList[i]; + auto user = use->getUser(); + switch (user->getOp()) + { + case kIROp_GetElementPtr: + case kIROp_GetElement: + case kIROp_Load: + case kIROp_Var: + { + auto newUserType = (IRType*)replaceImageElementType(user->getFullType(), newType); + if (newUserType != user->getFullType()) + { + user->setFullType(newUserType); + for (auto u = user->firstUse; u; u = u->nextUse) + { + if (typeReplacementWorkListSet.add(u)) + typeReplacementWorkList.add(u); + } + } + break; + } + case kIROp_Store: + { + auto store = as(user); + if (use == store->getValUse()) + { + auto ptr = store->getPtr(); + auto newPtrType = (IRType*)replaceImageElementType(ptr->getFullType(), newType); + if (newPtrType != ptr->getFullType()) + { + ptr->setFullType(newPtrType); + for (auto u = ptr->firstUse; u; u = u->nextUse) + { + if (typeReplacementWorkListSet.add(u)) + typeReplacementWorkList.add(u); + } + } + } + break; + } + } + } + } + } + + void resolveTextureFormat(IRModule* module) + { + for (auto globalInst : module->getGlobalInsts()) + { + if (as(globalInst->getDataType())) + { + resolveTextureFormatForParameter(globalInst, (IRTextureTypeBase*)globalInst->getDataType()); + } + else if (auto arrayType = as(globalInst->getDataType())) + { + if (as(arrayType->getElementType())) + { + resolveTextureFormatForParameter(globalInst, (IRTextureTypeBase*)arrayType->getElementType()); + } + } + } + } +} -- cgit v1.2.3