The complete ASL owner is shown directly below.
12345678
910111213141516
17pure func TileLayoutIsCube(layout: TileLayout) => boolean18begin19 return layout == TileLayout_CUBE_M16 ||20 layout == TileLayout_CUBE_M32 ||21 layout == TileLayout_CUBE_N8;22end;23
24pure func TileCubeDataTypeSupported(data_type: TileDataType) => boolean25begin26 let element_bits = TileElementBits(data_type);27 return element_bits != 64;28end;29
30pure func TileCubeCellRows(layout: TileLayout,31 data_type: TileDataType)32 => integer {0,4,8,16,32}33begin34 if !TileLayoutIsCube(layout) ||35 !TileCubeDataTypeSupported(data_type) then36 return 0;37 end;38 if layout == TileLayout_CUBE_M16 then return 16;39 elsif layout == TileLayout_CUBE_M32 then return 32;40 end;41 case TileElementBits(data_type) of42 when 32 => return 4;43 when 16 => return 8;44 when 8 => return 16;45 when 4 => return 32;46 otherwise => return 0;47 end;48end;49
50pure func TileCubeCellColumns(layout: TileLayout,51 data_type: TileDataType)52 => integer {0,1,2,4,8,16}53begin54 if !TileLayoutIsCube(layout) ||55 !TileCubeDataTypeSupported(data_type) then56 return 0;57 end;58 if layout == TileLayout_CUBE_N8 then return 8; end;59 case TileElementBits(data_type) of60 when 32 =>61 return if layout == TileLayout_CUBE_M16 then 2 else 1;62 when 16 =>63 return if layout == TileLayout_CUBE_M16 then 4 else 2;64 when 8 =>65 return if layout == TileLayout_CUBE_M16 then 8 else 4;66 when 4 =>67 return if layout == TileLayout_CUBE_M16 then 16 else 8;68 otherwise => return 0;69 end;70end;71
72pure func TileCubeAlignedExtent(value: integer {0..65535},73 quantum: integer {1..65535})74 => integer {0..65535}75begin76 if value == 0 then return 0; end;77 let groups: integer = ((value - 1) DIVRM quantum) + 1;78 let aligned: integer = groups * quantum;79 if aligned > 65535 then return 0; end;80 return aligned as integer {1..65535};81end;82
83pure func TileCubeStorageRows(layout: TileLayout,84 valid_rows: integer {0..65535},85 data_type: TileDataType)86 => integer {0..65535}87begin88 let cell_rows = TileCubeCellRows(layout, data_type);89 if cell_rows == 0 || valid_rows == 0 then return 0; end;90 if layout == TileLayout_CUBE_N8 ||91 layout == TileLayout_CUBE_M32 then92 return TileCubeAlignedExtent(valid_rows,93 cell_rows as integer {1..65535});94 end;95 if valid_rows > cell_rows then return 0; end;96 return cell_rows as integer {1..65535};97end;98
99pure func TileCubeStorageColumns(layout: TileLayout,100 valid_columns: integer {0..65535},101 data_type: TileDataType)102 => integer {0..65535}103begin104 let cell_columns = TileCubeCellColumns(layout, data_type);105 if cell_columns == 0 || valid_columns == 0 then return 0; end;106 return TileCubeAlignedExtent(valid_columns,107 cell_columns as integer {1..65535});108end;109
110pure func TileCubeKRepeat(layout: TileLayout,111 valid_rows: integer {0..65535},112 valid_columns: integer {0..65535},113 data_type: TileDataType)114 => integer {0..65535}115begin116 let cell_rows = TileCubeCellRows(layout, data_type);117 let cell_columns = TileCubeCellColumns(layout, data_type);118 if cell_rows == 0 || cell_columns == 0 then return 0; end;119 if layout == TileLayout_CUBE_N8 then120 let storage_rows = TileCubeStorageRows(layout, valid_rows, data_type);121 if storage_rows == 0 then return 0; end;122 let row_divisor = cell_rows as integer {1..32};123 return (storage_rows DIVRM row_divisor) as integer {1..65535};124 end;125 let storage_columns = TileCubeStorageColumns(126 layout, valid_columns, data_type);127 if storage_columns == 0 then return 0; end;128 let column_divisor = cell_columns as integer {1..16};129 return (storage_columns DIVRM column_divisor) as integer {1..65535};130end;131
132pure func TileCubeNRepeat(layout: TileLayout,133 valid_rows: integer {0..65535},134 valid_columns: integer {0..65535},135 data_type: TileDataType)136 => integer {0..8192}137begin138 if !TileLayoutIsCube(layout) ||139 !TileCubeDataTypeSupported(data_type) || valid_columns == 0 then140 return 0;141 end;142 if layout == TileLayout_CUBE_M32 then143 let storage_rows = TileCubeStorageRows(144 layout, valid_rows, data_type);145 if storage_rows == 0 then return 0; end;146 return (storage_rows DIVRM 32) as integer {1..2048};147 end;148 if layout != TileLayout_CUBE_N8 then return 1; end;149 let storage_columns = TileCubeStorageColumns(150 layout, valid_columns, data_type);151 if storage_columns == 0 then return 0; end;152 return (storage_columns DIVRM 8) as integer {1..8192};153end;154
155pure func TileCubeCellCount(layout: TileLayout,156 valid_rows: integer {0..65535},157 valid_columns: integer {0..65535},158 data_type: TileDataType)159 => integer {0..16384}160begin161 let k_repeat = TileCubeKRepeat(162 layout, valid_rows, valid_columns, data_type);163 let n_repeat = TileCubeNRepeat(164 layout, valid_rows, valid_columns, data_type);165 if k_repeat == 0 || n_repeat == 0 then return 0; end;166 let cells: integer = k_repeat * n_repeat;167 if cells > 16384 then return 0; end;168 return cells as integer {1..16384};169end;170
171readonly func TileCubeStorageElements(layout: TileLayout,172 valid_rows: integer {0..65535},173 valid_columns: integer {0..65535},174 data_type: TileDataType)175 => integer {0..16384}176begin177 let cells = TileCubeCellCount(178 layout, valid_rows, valid_columns, data_type);179 let cell_rows = TileCubeCellRows(layout, data_type);180 let cell_columns = TileCubeCellColumns(layout, data_type);181 if cells == 0 || cell_rows == 0 || cell_columns == 0 then return 0; end;182 let elements: integer = cells * cell_rows * cell_columns;183 if elements > PTO_MODEL_TILE_ELEMENTS then return 0; end;184 return elements as integer {1..16384};185end;186
187pure func TileCubeRequiredBytes(layout: TileLayout,188 valid_rows: integer {0..65535},189 valid_columns: integer {0..65535},190 data_type: TileDataType)191 => integer {0..262144}192begin193 let cells = TileCubeCellCount(194 layout, valid_rows, valid_columns, data_type);195 if cells == 0 then return 0; end;196 let required: integer = cells * PTO_TILE_CELL_BYTES;197 if required > 262144 then return 0; end;198 return required as integer {128..262144};199end;200
201readonly func TileCubeDescriptorShapeLegal(202 capacity_bytes: integer {0..262144},203 valid_rows: integer {0..65535},204 valid_columns: integer {0..65535},205 data_type: TileDataType,206 layout: TileLayout) => boolean207begin208 if !TileLayoutIsCube(layout) ||209 !TileCubeDataTypeSupported(data_type) ||210 !TileCapacityIsLegal(capacity_bytes) ||211 valid_rows == 0 || valid_columns == 0 then212 return FALSE;213 end;214 let storage_rows = TileCubeStorageRows(layout, valid_rows, data_type);215 let storage_columns = TileCubeStorageColumns(216 layout, valid_columns, data_type);217 let storage_elements = TileCubeStorageElements(218 layout, valid_rows, valid_columns, data_type);219 let required_bytes = TileCubeRequiredBytes(220 layout, valid_rows, valid_columns, data_type);221 return storage_rows != 0 && storage_columns != 0 &&222 storage_elements != 0 && required_bytes != 0 &&223 valid_rows <= storage_rows &&224 valid_columns <= storage_columns &&225 required_bytes <= capacity_bytes;226end;227
228pure func TileCubeCellElementIndex(229 layout: TileLayout,230 data_type: TileDataType,231 inner_row: integer {0..31},232 inner_column: integer {0..31})233 => integer {0..255}234begin235 let cell_rows = TileCubeCellRows(layout, data_type);236 let cell_columns = TileCubeCellColumns(layout, data_type);237 assert cell_rows != 0 && cell_columns != 0;238 assert inner_row < cell_rows && inner_column < cell_columns;239 if layout == TileLayout_CUBE_N8 then240 return (inner_column * cell_rows + inner_row)241 as integer {0..255};242 end;243 var mapped_column = inner_column;244 if layout == TileLayout_CUBE_M16 &&245 TileElementBits(data_type) == 4 then246 if inner_column < 4 then mapped_column = inner_column;247 elsif inner_column < 8 then248 mapped_column = (inner_column + 4) as integer {0..31};249 elsif inner_column < 12 then250 mapped_column = (inner_column - 4) as integer {0..31};251 else mapped_column = inner_column;252 end;253 end;254 return (inner_row * cell_columns + mapped_column)255 as integer {0..255};256end;257
258readonly func TileCubePayloadIndex(259 tile: TileInfo,260 row: integer {0..65535},261 column: integer {0..65535})262 => ModelTileElementIndex263begin264 assert TileLayoutIsCube(tile.layout);265 assert row < tile.rows && column < tile.columns;266 let cell_rows = TileCubeCellRows(tile.layout, tile.data_type);267 let cell_columns = TileCubeCellColumns(tile.layout, tile.data_type);268 let k_repeat = TileCubeKRepeat(tile.layout, tile.valid_rows,269 tile.valid_columns, tile.data_type);270 assert cell_rows != 0 && cell_columns != 0 && k_repeat != 0;271 let row_divisor = cell_rows as integer {1..32};272 let column_divisor = cell_columns as integer {1..16};273 var cell_index: integer = 0;274 var inner_row: integer = 0;275 var inner_column: integer = 0;276 if tile.layout == TileLayout_CUBE_N8 then277 let cell_k = (row DIVRM row_divisor) as integer {0..16383};278 let cell_n = (column DIVRM column_divisor) as integer {0..8191};279 cell_index = cell_n * k_repeat + cell_k;280 inner_row = row MOD row_divisor;281 inner_column = column MOD column_divisor;282 elsif tile.layout == TileLayout_CUBE_M32 then283 let cell_row = (row DIVRM row_divisor)284 as integer {0..2047};285 let cell_column = (column DIVRM column_divisor)286 as integer {0..65535};287 cell_index = cell_row * k_repeat + cell_column;288 inner_row = row MOD row_divisor;289 inner_column = column MOD column_divisor;290 else291 cell_index = column DIVRM column_divisor;292 inner_row = row;293 inner_column = column MOD column_divisor;294 end;295 let cell_elements: integer = cell_rows * cell_columns;296 let local = TileCubeCellElementIndex(tile.layout, tile.data_type,297 inner_row as integer {0..31}, inner_column as integer {0..31});298 let index: integer = cell_index * cell_elements + local;299 assert index < PTO_MODEL_TILE_ELEMENTS;300 return index as ModelTileElementIndex;301end;302