* @~English * @brief Interpret a Data Format Descriptor for a simple format. * * Handles "simple" cases that can be translated to things a GPU can access. * For simplicity, it ignores the compressed formats, which are generally a * single sample (and I believe are all defined to be little-endian in their * in-memory layout, even if some documentation confuses this). Focuses on * the layout
| 62 | * in format names in the Vulkan specification where G == Y, R = Cr and B = Cb. |
| 63 | **/ |
| 64 | enum InterpretDFDResult interpretDFD(const uint32_t *DFD, |
| 65 | InterpretedDFDChannel *R, |
| 66 | InterpretedDFDChannel *G, |
| 67 | InterpretedDFDChannel *B, |
| 68 | InterpretedDFDChannel *A, |
| 69 | uint32_t *wordBytes) |
| 70 | { |
| 71 | /* DFD points to the whole descriptor, not the basic descriptor block. */ |
| 72 | /* Make everything else relative to the basic descriptor block. */ |
| 73 | const uint32_t *BDFDB = DFD+1; |
| 74 | |
| 75 | uint32_t numSamples = KHR_DFDSAMPLECOUNT(BDFDB); |
| 76 | if (numSamples == 0) |
| 77 | return i_UNSUPPORTED_CHANNEL_TYPES; |
| 78 | |
| 79 | int determinedEndianness = 0; |
| 80 | enum InterpretDFDResult result = 0; /* Build this up incrementally. */ |
| 81 | |
| 82 | bool isDepthStencil = false; |
| 83 | |
| 84 | /* Clear these so following code doesn't get confused. */ |
| 85 | R->offset = R->size = 0; |
| 86 | G->offset = G->size = 0; |
| 87 | B->offset = B->size = 0; |
| 88 | A->offset = A->size = 0; |
| 89 | |
| 90 | /* First rule out the multiple planes case (trivially) */ |
| 91 | /* - that is, we check that only bytesPlane0 is non-zero. */ |
| 92 | /* This means we don't handle multi-plane YUV, even if the API could. */ |
| 93 | /* (We rely on KHR_DF_WORD_BYTESPLANE0..3 being the same and */ |
| 94 | /* KHR_DF_WORD_BYTESPLANE4..7 being the same as a short cut.) */ |
| 95 | if ((BDFDB[KHR_DF_WORD_BYTESPLANE0] & ~KHR_DF_MASK_BYTESPLANE0) |
| 96 | || BDFDB[KHR_DF_WORD_BYTESPLANE4]) return i_UNSUPPORTED_MULTIPLE_PLANES; |
| 97 | |
| 98 | /* If this is a packed format, we work out our offsets differently. */ |
| 99 | /* We assume a packed format has channels that aren't byte-aligned. */ |
| 100 | /* If we have a format in which every channel is byte-aligned *and* packed, */ |
| 101 | /* we have the RGBA/ABGR ambiguity; we *probably* don't want the packed */ |
| 102 | /* version in this case, and if hardware has to pack it and swizzle, */ |
| 103 | /* that's up to the hardware to special-case. */ |
| 104 | for (uint32_t sampleCounter = 0; sampleCounter < numSamples; ++sampleCounter) { |
| 105 | uint32_t offset = KHR_DFDSVAL(BDFDB, sampleCounter, BITOFFSET); |
| 106 | uint32_t length = KHR_DFDSVAL(BDFDB, sampleCounter, BITLENGTH) + 1; |
| 107 | if ((offset & 0x7U) || ((offset + length) & 0x7U)) { |
| 108 | result |= i_PACKED_FORMAT_BIT; |
| 109 | /* Once we're packed, we're packed, no need to keep checking. */ |
| 110 | break; |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | // Check data types. |
| 115 | bool hasSigned = false; |
| 116 | bool hasFloat = false; |
| 117 | bool hasNormalized = false; |
| 118 | bool hasFixed = false; |
| 119 | khr_df_model_e model = KHR_DFDVAL(BDFDB, MODEL); |
| 120 | |
| 121 | // Note: We're ignoring 9995, which is weird and worth special-casing |