Comments in header
| 4714 | |
| 4715 | // Comments in header |
| 4716 | Id Builder::accessChainLoad(Decoration precision, Decoration l_nonUniform, |
| 4717 | Decoration r_nonUniform, Id resultType, spv::MemoryAccessMask memoryAccess, |
| 4718 | spv::Scope scope, unsigned int alignment) |
| 4719 | { |
| 4720 | Id id; |
| 4721 | |
| 4722 | if (accessChain.isRValue) { |
| 4723 | // transfer access chain, but try to stay in registers |
| 4724 | transferAccessChainSwizzle(false); |
| 4725 | if (accessChain.indexChain.size() > 0) { |
| 4726 | Id swizzleBase = accessChain.preSwizzleBaseType != NoType ? accessChain.preSwizzleBaseType : resultType; |
| 4727 | |
| 4728 | // if all the accesses are constants, we can use OpCompositeExtract |
| 4729 | std::vector<unsigned> indexes; |
| 4730 | bool constant = true; |
| 4731 | for (int i = 0; i < (int)accessChain.indexChain.size(); ++i) { |
| 4732 | if (isConstantScalar(accessChain.indexChain[i])) |
| 4733 | indexes.push_back(getConstantScalar(accessChain.indexChain[i])); |
| 4734 | else { |
| 4735 | constant = false; |
| 4736 | break; |
| 4737 | } |
| 4738 | } |
| 4739 | |
| 4740 | if (constant) { |
| 4741 | id = createCompositeExtract(accessChain.base, swizzleBase, indexes); |
| 4742 | setPrecision(id, precision); |
| 4743 | } else if (isVector(accessChain.base) || isCooperativeVector(accessChain.base)) { |
| 4744 | assert(accessChain.indexChain.size() == 1); |
| 4745 | id = createVectorExtractDynamic(accessChain.base, resultType, accessChain.indexChain[0]); |
| 4746 | } else { |
| 4747 | Id lValue = NoResult; |
| 4748 | if (spvVersion >= Spv_1_4 && isValidInitializer(accessChain.base)) { |
| 4749 | // make a new function variable for this r-value, using an initializer, |
| 4750 | // and mark it as NonWritable so that downstream it can be detected as a lookup |
| 4751 | // table |
| 4752 | lValue = createVariable(NoPrecision, StorageClass::Function, getTypeId(accessChain.base), |
| 4753 | "indexable", accessChain.base); |
| 4754 | addDecoration(lValue, Decoration::NonWritable); |
| 4755 | } else { |
| 4756 | lValue = createVariable(NoPrecision, StorageClass::Function, getTypeId(accessChain.base), |
| 4757 | "indexable"); |
| 4758 | // store into it |
| 4759 | createStore(accessChain.base, lValue); |
| 4760 | } |
| 4761 | // move base to the new variable |
| 4762 | accessChain.base = lValue; |
| 4763 | accessChain.isRValue = false; |
| 4764 | |
| 4765 | // load through the access chain |
| 4766 | id = createLoad(collapseAccessChain(), precision); |
| 4767 | } |
| 4768 | } else |
| 4769 | id = accessChain.base; // no precision, it was set when this was defined |
| 4770 | } else { |
| 4771 | transferAccessChainSwizzle(true); |
| 4772 | |
| 4773 | // take LSB of alignment |