Returns the offset from the base pointer to the desired mip and slice Slice is either a texture from an array, a face from a cubemap, or a 2D slice of a volume texture
| 1082 | // Returns the offset from the base pointer to the desired mip and slice |
| 1083 | // Slice is either a texture from an array, a face from a cubemap, or a 2D slice of a volume texture |
| 1084 | inline ddspp_constexpr unsigned int get_offset(const Descriptor& desc, const unsigned int mip, const unsigned int slice) |
| 1085 | { |
| 1086 | // The mip/slice arrangement is different between texture arrays and volume textures |
| 1087 | // |
| 1088 | // Arrays |
| 1089 | // __________ _____ __ __________ _____ __ __________ _____ __ |
| 1090 | // | || ||__|| || ||__|| || ||__| |
| 1091 | // | ||_____| | ||_____| | ||_____| |
| 1092 | // | | | | | | |
| 1093 | // |__________| |__________| |__________| |
| 1094 | // |
| 1095 | // Volume |
| 1096 | // __________ __________ __________ _____ _____ _____ __ __ __ |
| 1097 | // | || || || || || ||__||__||__| |
| 1098 | // | || || ||_____||_____||_____| |
| 1099 | // | || || | |
| 1100 | // |__________||__________||__________| |
| 1101 | // |
| 1102 | |
| 1103 | unsigned long long offset = 0; |
| 1104 | |
| 1105 | if (desc.type == Texture3D) |
| 1106 | { |
| 1107 | for (unsigned int m = 0; m <= mip; ++m) |
| 1108 | { |
| 1109 | unsigned int mipWidth = (desc.width >> m) > 1 ? (desc.width >> m) : 1; |
| 1110 | unsigned int mipHeight = (desc.height >> m) > 1 ? (desc.height >> m) : 1; |
| 1111 | unsigned int mipBlocksWidth = (mipWidth + desc.blockWidth - 1) / desc.blockWidth; |
| 1112 | unsigned int mipBlocksHeight = (mipHeight + desc.blockHeight - 1) / desc.blockHeight; |
| 1113 | unsigned long long mipSize = mipBlocksWidth * mipBlocksHeight * desc.bitsPerPixelOrBlock; |
| 1114 | offset += mipSize * ((m == mip) ? slice : desc.numMips); |
| 1115 | } |
| 1116 | } |
| 1117 | else |
| 1118 | { |
| 1119 | unsigned long long mipChainSize = 0; |
| 1120 | |
| 1121 | for (unsigned int m = 0; m < desc.numMips; ++m) |
| 1122 | { |
| 1123 | unsigned int mipWidth = (desc.width >> m) > 1 ? (desc.width >> m) : 1; |
| 1124 | unsigned int mipHeight = (desc.height >> m) > 1 ? (desc.height >> m) : 1; |
| 1125 | unsigned int mipBlocksWidth = (mipWidth + desc.blockWidth - 1) / desc.blockWidth; |
| 1126 | unsigned int mipBlocksHeight = (mipHeight + desc.blockHeight - 1) / desc.blockHeight; |
| 1127 | mipChainSize += mipBlocksWidth * mipBlocksHeight * desc.bitsPerPixelOrBlock; |
| 1128 | } |
| 1129 | |
| 1130 | offset += mipChainSize * slice; |
| 1131 | |
| 1132 | for (unsigned int m = 0; m < mip; ++m) |
| 1133 | { |
| 1134 | unsigned int mipWidth = (desc.width >> m) > 1 ? (desc.width >> m) : 1; |
| 1135 | unsigned int mipHeight = (desc.height >> m) > 1 ? (desc.height >> m) : 1; |
| 1136 | unsigned int mipBlocksWidth = (mipWidth + desc.blockWidth - 1) / desc.blockWidth; |
| 1137 | unsigned int mipBlocksHeight = (mipHeight + desc.blockHeight - 1) / desc.blockHeight; |
| 1138 | offset += mipBlocksWidth * mipBlocksHeight * desc.bitsPerPixelOrBlock; |
| 1139 | } |
| 1140 | } |
| 1141 |