1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright (C) 2022 Collabora, Ltd.
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
13bf215546Sopenharmony_ci * Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21bf215546Sopenharmony_ci * SOFTWARE.
22bf215546Sopenharmony_ci */
23bf215546Sopenharmony_ci
24bf215546Sopenharmony_ci#include "pan_texture.h"
25bf215546Sopenharmony_ci
26bf215546Sopenharmony_ci#include <gtest/gtest.h>
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ciTEST(BlockSize, Linear)
29bf215546Sopenharmony_ci{
30bf215546Sopenharmony_ci   enum pipe_format format[] = {
31bf215546Sopenharmony_ci      PIPE_FORMAT_R32G32B32_FLOAT,
32bf215546Sopenharmony_ci      PIPE_FORMAT_R8G8B8_UNORM,
33bf215546Sopenharmony_ci      PIPE_FORMAT_ETC2_RGB8,
34bf215546Sopenharmony_ci      PIPE_FORMAT_ASTC_5x5
35bf215546Sopenharmony_ci   };
36bf215546Sopenharmony_ci
37bf215546Sopenharmony_ci   for (unsigned i = 0; i < ARRAY_SIZE(format); ++i) {
38bf215546Sopenharmony_ci      struct pan_block_size blk = panfrost_block_size(DRM_FORMAT_MOD_LINEAR, format[i]);
39bf215546Sopenharmony_ci
40bf215546Sopenharmony_ci      EXPECT_EQ(blk.width, 1);
41bf215546Sopenharmony_ci      EXPECT_EQ(blk.height, 1);
42bf215546Sopenharmony_ci   }
43bf215546Sopenharmony_ci}
44bf215546Sopenharmony_ci
45bf215546Sopenharmony_ciTEST(BlockSize, UInterleavedRegular)
46bf215546Sopenharmony_ci{
47bf215546Sopenharmony_ci   enum pipe_format format[] = {
48bf215546Sopenharmony_ci      PIPE_FORMAT_R32G32B32_FLOAT,
49bf215546Sopenharmony_ci      PIPE_FORMAT_R8G8B8_UNORM,
50bf215546Sopenharmony_ci   };
51bf215546Sopenharmony_ci
52bf215546Sopenharmony_ci   for (unsigned i = 0; i < ARRAY_SIZE(format); ++i) {
53bf215546Sopenharmony_ci      struct pan_block_size blk = panfrost_block_size(DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED, format[i]);
54bf215546Sopenharmony_ci
55bf215546Sopenharmony_ci      EXPECT_EQ(blk.width, 16);
56bf215546Sopenharmony_ci      EXPECT_EQ(blk.height, 16);
57bf215546Sopenharmony_ci   }
58bf215546Sopenharmony_ci}
59bf215546Sopenharmony_ci
60bf215546Sopenharmony_ciTEST(BlockSize, UInterleavedBlockCompressed)
61bf215546Sopenharmony_ci{
62bf215546Sopenharmony_ci   enum pipe_format format[] = {
63bf215546Sopenharmony_ci      PIPE_FORMAT_ETC2_RGB8,
64bf215546Sopenharmony_ci      PIPE_FORMAT_ASTC_5x5
65bf215546Sopenharmony_ci   };
66bf215546Sopenharmony_ci
67bf215546Sopenharmony_ci   for (unsigned i = 0; i < ARRAY_SIZE(format); ++i) {
68bf215546Sopenharmony_ci      struct pan_block_size blk = panfrost_block_size(DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED, format[i]);
69bf215546Sopenharmony_ci
70bf215546Sopenharmony_ci      EXPECT_EQ(blk.width, 4);
71bf215546Sopenharmony_ci      EXPECT_EQ(blk.height, 4);
72bf215546Sopenharmony_ci   }
73bf215546Sopenharmony_ci}
74bf215546Sopenharmony_ci
75bf215546Sopenharmony_ciTEST(BlockSize, AFBCFormatInvariant16x16)
76bf215546Sopenharmony_ci{
77bf215546Sopenharmony_ci   enum pipe_format format[] = {
78bf215546Sopenharmony_ci      PIPE_FORMAT_R32G32B32_FLOAT,
79bf215546Sopenharmony_ci      PIPE_FORMAT_R8G8B8_UNORM,
80bf215546Sopenharmony_ci      PIPE_FORMAT_ETC2_RGB8,
81bf215546Sopenharmony_ci      PIPE_FORMAT_ASTC_5x5
82bf215546Sopenharmony_ci   };
83bf215546Sopenharmony_ci
84bf215546Sopenharmony_ci   uint64_t modifier = DRM_FORMAT_MOD_ARM_AFBC(
85bf215546Sopenharmony_ci                AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
86bf215546Sopenharmony_ci                AFBC_FORMAT_MOD_SPARSE |
87bf215546Sopenharmony_ci                AFBC_FORMAT_MOD_YTR);
88bf215546Sopenharmony_ci
89bf215546Sopenharmony_ci   for (unsigned i = 0; i < ARRAY_SIZE(format); ++i) {
90bf215546Sopenharmony_ci      struct pan_block_size blk = panfrost_block_size(modifier, format[i]);
91bf215546Sopenharmony_ci
92bf215546Sopenharmony_ci      EXPECT_EQ(blk.width, 16);
93bf215546Sopenharmony_ci      EXPECT_EQ(blk.height, 16);
94bf215546Sopenharmony_ci   }
95bf215546Sopenharmony_ci}
96bf215546Sopenharmony_ci
97bf215546Sopenharmony_ciTEST(BlockSize, AFBCFormatInvariant32x8)
98bf215546Sopenharmony_ci{
99bf215546Sopenharmony_ci   enum pipe_format format[] = {
100bf215546Sopenharmony_ci      PIPE_FORMAT_R32G32B32_FLOAT,
101bf215546Sopenharmony_ci      PIPE_FORMAT_R8G8B8_UNORM,
102bf215546Sopenharmony_ci      PIPE_FORMAT_ETC2_RGB8,
103bf215546Sopenharmony_ci      PIPE_FORMAT_ASTC_5x5
104bf215546Sopenharmony_ci   };
105bf215546Sopenharmony_ci
106bf215546Sopenharmony_ci   uint64_t modifier = DRM_FORMAT_MOD_ARM_AFBC(
107bf215546Sopenharmony_ci                AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
108bf215546Sopenharmony_ci                AFBC_FORMAT_MOD_SPARSE |
109bf215546Sopenharmony_ci                AFBC_FORMAT_MOD_YTR);
110bf215546Sopenharmony_ci
111bf215546Sopenharmony_ci   for (unsigned i = 0; i < ARRAY_SIZE(format); ++i) {
112bf215546Sopenharmony_ci      struct pan_block_size blk = panfrost_block_size(modifier, format[i]);
113bf215546Sopenharmony_ci
114bf215546Sopenharmony_ci      EXPECT_EQ(blk.width, 32);
115bf215546Sopenharmony_ci      EXPECT_EQ(blk.height, 8);
116bf215546Sopenharmony_ci   }
117bf215546Sopenharmony_ci}
118bf215546Sopenharmony_ci
119bf215546Sopenharmony_ciTEST(BlockSize, AFBCSuperblock16x16)
120bf215546Sopenharmony_ci{
121bf215546Sopenharmony_ci   uint64_t modifier = DRM_FORMAT_MOD_ARM_AFBC(
122bf215546Sopenharmony_ci                AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
123bf215546Sopenharmony_ci                AFBC_FORMAT_MOD_SPARSE |
124bf215546Sopenharmony_ci                AFBC_FORMAT_MOD_YTR);
125bf215546Sopenharmony_ci
126bf215546Sopenharmony_ci   EXPECT_EQ(panfrost_afbc_superblock_size(modifier).width, 16);
127bf215546Sopenharmony_ci   EXPECT_EQ(panfrost_afbc_superblock_width(modifier), 16);
128bf215546Sopenharmony_ci
129bf215546Sopenharmony_ci   EXPECT_EQ(panfrost_afbc_superblock_size(modifier).height, 16);
130bf215546Sopenharmony_ci   EXPECT_EQ(panfrost_afbc_superblock_height(modifier), 16);
131bf215546Sopenharmony_ci
132bf215546Sopenharmony_ci   EXPECT_FALSE(panfrost_afbc_is_wide(modifier));
133bf215546Sopenharmony_ci}
134bf215546Sopenharmony_ci
135bf215546Sopenharmony_ciTEST(BlockSize, AFBCSuperblock32x8)
136bf215546Sopenharmony_ci{
137bf215546Sopenharmony_ci   uint64_t modifier = DRM_FORMAT_MOD_ARM_AFBC(
138bf215546Sopenharmony_ci                AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
139bf215546Sopenharmony_ci                AFBC_FORMAT_MOD_SPARSE);
140bf215546Sopenharmony_ci
141bf215546Sopenharmony_ci   EXPECT_EQ(panfrost_afbc_superblock_size(modifier).width, 32);
142bf215546Sopenharmony_ci   EXPECT_EQ(panfrost_afbc_superblock_width(modifier), 32);
143bf215546Sopenharmony_ci
144bf215546Sopenharmony_ci   EXPECT_EQ(panfrost_afbc_superblock_size(modifier).height, 8);
145bf215546Sopenharmony_ci   EXPECT_EQ(panfrost_afbc_superblock_height(modifier), 8);
146bf215546Sopenharmony_ci
147bf215546Sopenharmony_ci   EXPECT_TRUE(panfrost_afbc_is_wide(modifier));
148bf215546Sopenharmony_ci}
149bf215546Sopenharmony_ci
150bf215546Sopenharmony_ciTEST(BlockSize, AFBCSuperblock64x4)
151bf215546Sopenharmony_ci{
152bf215546Sopenharmony_ci   uint64_t modifier = DRM_FORMAT_MOD_ARM_AFBC(
153bf215546Sopenharmony_ci                AFBC_FORMAT_MOD_BLOCK_SIZE_64x4 |
154bf215546Sopenharmony_ci                AFBC_FORMAT_MOD_SPARSE);
155bf215546Sopenharmony_ci
156bf215546Sopenharmony_ci   EXPECT_EQ(panfrost_afbc_superblock_size(modifier).width, 64);
157bf215546Sopenharmony_ci   EXPECT_EQ(panfrost_afbc_superblock_width(modifier), 64);
158bf215546Sopenharmony_ci
159bf215546Sopenharmony_ci   EXPECT_EQ(panfrost_afbc_superblock_size(modifier).height, 4);
160bf215546Sopenharmony_ci   EXPECT_EQ(panfrost_afbc_superblock_height(modifier), 4);
161bf215546Sopenharmony_ci
162bf215546Sopenharmony_ci   EXPECT_TRUE(panfrost_afbc_is_wide(modifier));
163bf215546Sopenharmony_ci}
164bf215546Sopenharmony_ci
165bf215546Sopenharmony_ci/* Calculate Bifrost line stride, since we have reference formulas for Bifrost
166bf215546Sopenharmony_ci * stride calculations.
167bf215546Sopenharmony_ci */
168bf215546Sopenharmony_cistatic uint32_t pan_afbc_line_stride(uint64_t modifier, uint32_t width)
169bf215546Sopenharmony_ci{
170bf215546Sopenharmony_ci   return pan_afbc_stride_blocks(modifier, pan_afbc_row_stride(modifier, width));
171bf215546Sopenharmony_ci}
172bf215546Sopenharmony_ci
173bf215546Sopenharmony_ci/* Which form of the stride we specify is hardware specific (row stride for
174bf215546Sopenharmony_ci * Valhall, line stride for Bifrost). However, the layout code is hardware
175bf215546Sopenharmony_ci * independent, so we test both row stride and line stride calculations.
176bf215546Sopenharmony_ci */
177bf215546Sopenharmony_ciTEST(AFBCStride, Linear)
178bf215546Sopenharmony_ci{
179bf215546Sopenharmony_ci   uint64_t modifiers[] = {
180bf215546Sopenharmony_ci      DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
181bf215546Sopenharmony_ci                              AFBC_FORMAT_MOD_SPARSE),
182bf215546Sopenharmony_ci      DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
183bf215546Sopenharmony_ci                              AFBC_FORMAT_MOD_SPARSE),
184bf215546Sopenharmony_ci      DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_64x4 |
185bf215546Sopenharmony_ci                              AFBC_FORMAT_MOD_SPARSE),
186bf215546Sopenharmony_ci   };
187bf215546Sopenharmony_ci
188bf215546Sopenharmony_ci   for (unsigned m = 0; m < ARRAY_SIZE(modifiers); ++m) {
189bf215546Sopenharmony_ci      uint64_t modifier = modifiers[m];
190bf215546Sopenharmony_ci
191bf215546Sopenharmony_ci      uint32_t sw = panfrost_afbc_superblock_width(modifier);
192bf215546Sopenharmony_ci      uint32_t cases[] = { 1, 4, 17, 39 };
193bf215546Sopenharmony_ci
194bf215546Sopenharmony_ci      for (unsigned i = 0; i < ARRAY_SIZE(cases); ++i) {
195bf215546Sopenharmony_ci         uint32_t width = sw * cases[i];
196bf215546Sopenharmony_ci
197bf215546Sopenharmony_ci         EXPECT_EQ(pan_afbc_row_stride(modifier, width),
198bf215546Sopenharmony_ci               16 * DIV_ROUND_UP(width, sw));
199bf215546Sopenharmony_ci
200bf215546Sopenharmony_ci         EXPECT_EQ(pan_afbc_line_stride(modifier, width),
201bf215546Sopenharmony_ci               DIV_ROUND_UP(width, sw));
202bf215546Sopenharmony_ci      }
203bf215546Sopenharmony_ci   }
204bf215546Sopenharmony_ci}
205bf215546Sopenharmony_ci
206bf215546Sopenharmony_ciTEST(AFBCStride, Tiled)
207bf215546Sopenharmony_ci{
208bf215546Sopenharmony_ci   uint64_t modifiers[] = {
209bf215546Sopenharmony_ci      DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
210bf215546Sopenharmony_ci                              AFBC_FORMAT_MOD_TILED |
211bf215546Sopenharmony_ci                              AFBC_FORMAT_MOD_SPARSE),
212bf215546Sopenharmony_ci      DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
213bf215546Sopenharmony_ci                              AFBC_FORMAT_MOD_TILED |
214bf215546Sopenharmony_ci                              AFBC_FORMAT_MOD_SPARSE),
215bf215546Sopenharmony_ci      DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_64x4 |
216bf215546Sopenharmony_ci                              AFBC_FORMAT_MOD_TILED |
217bf215546Sopenharmony_ci                              AFBC_FORMAT_MOD_SPARSE),
218bf215546Sopenharmony_ci   };
219bf215546Sopenharmony_ci
220bf215546Sopenharmony_ci   for (unsigned m = 0; m < ARRAY_SIZE(modifiers); ++m) {
221bf215546Sopenharmony_ci      uint64_t modifier = modifiers[m];
222bf215546Sopenharmony_ci
223bf215546Sopenharmony_ci      uint32_t sw = panfrost_afbc_superblock_width(modifier);
224bf215546Sopenharmony_ci      uint32_t cases[] = { 1, 4, 17, 39 };
225bf215546Sopenharmony_ci
226bf215546Sopenharmony_ci      for (unsigned i = 0; i < ARRAY_SIZE(cases); ++i) {
227bf215546Sopenharmony_ci         uint32_t width = sw * 8 * cases[i];
228bf215546Sopenharmony_ci
229bf215546Sopenharmony_ci         EXPECT_EQ(pan_afbc_row_stride(modifier, width),
230bf215546Sopenharmony_ci               16 * DIV_ROUND_UP(width, (sw * 8)) * 8 * 8);
231bf215546Sopenharmony_ci
232bf215546Sopenharmony_ci         EXPECT_EQ(pan_afbc_line_stride(modifier, width),
233bf215546Sopenharmony_ci               DIV_ROUND_UP(width, sw * 8) * 8);
234bf215546Sopenharmony_ci      }
235bf215546Sopenharmony_ci   }
236bf215546Sopenharmony_ci}
237bf215546Sopenharmony_ci
238bf215546Sopenharmony_ciTEST(LegacyStride, FromLegacyLinear)
239bf215546Sopenharmony_ci{
240bf215546Sopenharmony_ci   EXPECT_EQ(panfrost_from_legacy_stride(1920 * 4, PIPE_FORMAT_R8G8B8A8_UINT, DRM_FORMAT_MOD_LINEAR), 1920 * 4);
241bf215546Sopenharmony_ci   EXPECT_EQ(panfrost_from_legacy_stride(53, PIPE_FORMAT_R8_SNORM, DRM_FORMAT_MOD_LINEAR), 53);
242bf215546Sopenharmony_ci   EXPECT_EQ(panfrost_from_legacy_stride(60, PIPE_FORMAT_ETC2_RGB8, DRM_FORMAT_MOD_LINEAR), 60);
243bf215546Sopenharmony_ci}
244bf215546Sopenharmony_ci
245bf215546Sopenharmony_ciTEST(LegacyStride, FromLegacyInterleaved)
246bf215546Sopenharmony_ci{
247bf215546Sopenharmony_ci   EXPECT_EQ(panfrost_from_legacy_stride(1920 * 4, PIPE_FORMAT_R8G8B8A8_UINT,
248bf215546Sopenharmony_ci            DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED),
249bf215546Sopenharmony_ci            1920 * 4 * 16);
250bf215546Sopenharmony_ci
251bf215546Sopenharmony_ci   EXPECT_EQ(panfrost_from_legacy_stride(53, PIPE_FORMAT_R8_SNORM,
252bf215546Sopenharmony_ci            DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED), 53 * 16);
253bf215546Sopenharmony_ci
254bf215546Sopenharmony_ci   EXPECT_EQ(panfrost_from_legacy_stride(60, PIPE_FORMAT_ETC2_RGB8,
255bf215546Sopenharmony_ci            DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED), 60 * 4);
256bf215546Sopenharmony_ci}
257bf215546Sopenharmony_ci
258bf215546Sopenharmony_ciTEST(LegacyStride, FromLegacyAFBC)
259bf215546Sopenharmony_ci{
260bf215546Sopenharmony_ci   uint64_t modifier = DRM_FORMAT_MOD_ARM_AFBC(
261bf215546Sopenharmony_ci                AFBC_FORMAT_MOD_BLOCK_SIZE_32x8 |
262bf215546Sopenharmony_ci                AFBC_FORMAT_MOD_SPARSE |
263bf215546Sopenharmony_ci                AFBC_FORMAT_MOD_YTR);
264bf215546Sopenharmony_ci
265bf215546Sopenharmony_ci   EXPECT_EQ(panfrost_from_legacy_stride(1920 * 4, PIPE_FORMAT_R8G8B8A8_UINT, modifier), 60 * 16);
266bf215546Sopenharmony_ci   EXPECT_EQ(panfrost_from_legacy_stride(64, PIPE_FORMAT_R8_SNORM, modifier), 2 * 16);
267bf215546Sopenharmony_ci}
268bf215546Sopenharmony_ci
269bf215546Sopenharmony_ci/* dEQP-GLES3.functional.texture.format.compressed.etc1_2d_pot */
270bf215546Sopenharmony_ciTEST(Layout, ImplicitLayoutInterleavedETC2)
271bf215546Sopenharmony_ci{
272bf215546Sopenharmony_ci   struct pan_image_layout l = {
273bf215546Sopenharmony_ci      .modifier = DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED,
274bf215546Sopenharmony_ci      .format = PIPE_FORMAT_ETC2_RGB8,
275bf215546Sopenharmony_ci      .width = 128,
276bf215546Sopenharmony_ci      .height = 128,
277bf215546Sopenharmony_ci      .depth = 1,
278bf215546Sopenharmony_ci      .nr_samples = 1,
279bf215546Sopenharmony_ci      .dim = MALI_TEXTURE_DIMENSION_2D,
280bf215546Sopenharmony_ci      .nr_slices = 8
281bf215546Sopenharmony_ci   };
282bf215546Sopenharmony_ci
283bf215546Sopenharmony_ci   unsigned offsets[9] = {
284bf215546Sopenharmony_ci      0, 8192, 10240, 10752, 10880, 11008, 11136, 11264, 11392
285bf215546Sopenharmony_ci   };
286bf215546Sopenharmony_ci
287bf215546Sopenharmony_ci   ASSERT_TRUE(pan_image_layout_init(&l, NULL));
288bf215546Sopenharmony_ci
289bf215546Sopenharmony_ci   for (unsigned i = 0; i < 8; ++i) {
290bf215546Sopenharmony_ci      unsigned size = (offsets[i + 1] - offsets[i]);
291bf215546Sopenharmony_ci      EXPECT_EQ(l.slices[i].offset, offsets[i]);
292bf215546Sopenharmony_ci
293bf215546Sopenharmony_ci      if (size == 64)
294bf215546Sopenharmony_ci         EXPECT_TRUE(l.slices[i].size < 64);
295bf215546Sopenharmony_ci      else
296bf215546Sopenharmony_ci         EXPECT_EQ(l.slices[i].size, size);
297bf215546Sopenharmony_ci   }
298bf215546Sopenharmony_ci}
299bf215546Sopenharmony_ci
300bf215546Sopenharmony_ciTEST(Layout, ImplicitLayoutInterleavedASTC5x5)
301bf215546Sopenharmony_ci{
302bf215546Sopenharmony_ci   struct pan_image_layout l = {
303bf215546Sopenharmony_ci      .modifier = DRM_FORMAT_MOD_ARM_16X16_BLOCK_U_INTERLEAVED,
304bf215546Sopenharmony_ci      .format = PIPE_FORMAT_ASTC_5x5,
305bf215546Sopenharmony_ci      .width = 50,
306bf215546Sopenharmony_ci      .height = 50,
307bf215546Sopenharmony_ci      .depth = 1,
308bf215546Sopenharmony_ci      .nr_samples = 1,
309bf215546Sopenharmony_ci      .dim = MALI_TEXTURE_DIMENSION_2D,
310bf215546Sopenharmony_ci      .nr_slices = 1
311bf215546Sopenharmony_ci   };
312bf215546Sopenharmony_ci
313bf215546Sopenharmony_ci   ASSERT_TRUE(pan_image_layout_init(&l, NULL));
314bf215546Sopenharmony_ci
315bf215546Sopenharmony_ci   /* The image is 50x50 pixels, with 5x5 blocks. So it is a 10x10 grid of ASTC
316bf215546Sopenharmony_ci    * blocks. 4x4 tiles of ASTC blocks are u-interleaved, so we have to round up
317bf215546Sopenharmony_ci    * to a 12x12 grid. So we need space for 144 ASTC blocks. Each ASTC block is
318bf215546Sopenharmony_ci    * 16 bytes (128-bits), so we require 2304 bytes, with a row stride of 12 *
319bf215546Sopenharmony_ci    * 16 * 4 = 192 bytes.
320bf215546Sopenharmony_ci    */
321bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].offset, 0);
322bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].row_stride, 768);
323bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].surface_stride, 2304);
324bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].size, 2304);
325bf215546Sopenharmony_ci}
326bf215546Sopenharmony_ci
327bf215546Sopenharmony_ciTEST(Layout, ImplicitLayoutLinearASTC5x5)
328bf215546Sopenharmony_ci{
329bf215546Sopenharmony_ci   struct pan_image_layout l = {
330bf215546Sopenharmony_ci      .modifier = DRM_FORMAT_MOD_LINEAR,
331bf215546Sopenharmony_ci      .format = PIPE_FORMAT_ASTC_5x5,
332bf215546Sopenharmony_ci      .width = 50,
333bf215546Sopenharmony_ci      .height = 50,
334bf215546Sopenharmony_ci      .depth = 1,
335bf215546Sopenharmony_ci      .nr_samples = 1,
336bf215546Sopenharmony_ci      .dim = MALI_TEXTURE_DIMENSION_2D,
337bf215546Sopenharmony_ci      .nr_slices = 1
338bf215546Sopenharmony_ci   };
339bf215546Sopenharmony_ci
340bf215546Sopenharmony_ci   ASSERT_TRUE(pan_image_layout_init(&l, NULL));
341bf215546Sopenharmony_ci
342bf215546Sopenharmony_ci   /* The image is 50x50 pixels, with 5x5 blocks. So it is a 10x10 grid of ASTC
343bf215546Sopenharmony_ci    * blocks. Each ASTC block is 16 bytes, so the row stride is 160 bytes,
344bf215546Sopenharmony_ci    * rounded up to the cache line (192 bytes).  There are 10 rows, so we have
345bf215546Sopenharmony_ci    * 1920 bytes total.
346bf215546Sopenharmony_ci    */
347bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].offset, 0);
348bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].row_stride, 192);
349bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].surface_stride, 1920);
350bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].size, 1920);
351bf215546Sopenharmony_ci}
352bf215546Sopenharmony_ci
353bf215546Sopenharmony_ci/* dEQP-GLES3.functional.texture.format.unsized.rgba_unsigned_byte_3d_pot */
354bf215546Sopenharmony_ciTEST(AFBCLayout, Linear3D)
355bf215546Sopenharmony_ci{
356bf215546Sopenharmony_ci   uint64_t modifier = DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
357bf215546Sopenharmony_ci                        AFBC_FORMAT_MOD_SPARSE);
358bf215546Sopenharmony_ci
359bf215546Sopenharmony_ci   struct pan_image_layout l = {
360bf215546Sopenharmony_ci      .modifier = modifier,
361bf215546Sopenharmony_ci      .format = PIPE_FORMAT_R8G8B8A8_UNORM,
362bf215546Sopenharmony_ci      .width = 8,
363bf215546Sopenharmony_ci      .height = 32,
364bf215546Sopenharmony_ci      .depth = 16,
365bf215546Sopenharmony_ci      .nr_samples = 1,
366bf215546Sopenharmony_ci      .dim = MALI_TEXTURE_DIMENSION_3D,
367bf215546Sopenharmony_ci      .nr_slices = 1
368bf215546Sopenharmony_ci   };
369bf215546Sopenharmony_ci
370bf215546Sopenharmony_ci   ASSERT_TRUE(pan_image_layout_init(&l, NULL));
371bf215546Sopenharmony_ci
372bf215546Sopenharmony_ci   /* AFBC Surface stride is bytes between consecutive surface headers, which is
373bf215546Sopenharmony_ci    * the header size since this is a 3D texture. At superblock size 16x16, the 8x32
374bf215546Sopenharmony_ci    * layer has 1x2 superblocks, so the header size is 2 * 16 = 32 bytes,
375bf215546Sopenharmony_ci    * rounded up to cache line 64.
376bf215546Sopenharmony_ci    *
377bf215546Sopenharmony_ci    * There is only 1 superblock per row, so the row stride is the bytes per 1
378bf215546Sopenharmony_ci    * header block = 16.
379bf215546Sopenharmony_ci    *
380bf215546Sopenharmony_ci    * There are 16 layers of size 64 so afbc.header_size = 16 * 64 = 1024.
381bf215546Sopenharmony_ci    *
382bf215546Sopenharmony_ci    * Each 16x16 superblock consumes 16 * 16 * 4 = 1024 bytes. There are 2 * 1 *
383bf215546Sopenharmony_ci    * 16 superblocks in the image, so body size is 32768.
384bf215546Sopenharmony_ci    */
385bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].offset, 0);
386bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].row_stride, 16);
387bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].afbc.header_size, 1024);
388bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].afbc.body_size, 32768);
389bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].afbc.surface_stride, 64);
390bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].surface_stride, 2048); /* XXX: Not meaningful? */
391bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].size, 32768); /* XXX: Not used by anything and wrong */
392bf215546Sopenharmony_ci}
393bf215546Sopenharmony_ci
394bf215546Sopenharmony_ciTEST(AFBCLayout, Tiled16x16)
395bf215546Sopenharmony_ci{
396bf215546Sopenharmony_ci   uint64_t modifier = DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
397bf215546Sopenharmony_ci                        AFBC_FORMAT_MOD_TILED |
398bf215546Sopenharmony_ci                        AFBC_FORMAT_MOD_SPARSE);
399bf215546Sopenharmony_ci
400bf215546Sopenharmony_ci   struct pan_image_layout l = {
401bf215546Sopenharmony_ci      .modifier = modifier,
402bf215546Sopenharmony_ci      .format = PIPE_FORMAT_R8G8B8A8_UNORM,
403bf215546Sopenharmony_ci      .width = 917,
404bf215546Sopenharmony_ci      .height = 417,
405bf215546Sopenharmony_ci      .depth = 1,
406bf215546Sopenharmony_ci      .nr_samples = 1,
407bf215546Sopenharmony_ci      .dim = MALI_TEXTURE_DIMENSION_2D,
408bf215546Sopenharmony_ci      .nr_slices = 1
409bf215546Sopenharmony_ci   };
410bf215546Sopenharmony_ci
411bf215546Sopenharmony_ci   ASSERT_TRUE(pan_image_layout_init(&l, NULL));
412bf215546Sopenharmony_ci
413bf215546Sopenharmony_ci   /* The image is 917x417. Superblocks are 16x16, so there are 58x27
414bf215546Sopenharmony_ci    * superblocks. Superblocks are grouped into 8x8 tiles, so there are 8x4
415bf215546Sopenharmony_ci    * tiles of superblocks. So the row stride is 16 * 8 * 8 * 8 = 8192 bytes.
416bf215546Sopenharmony_ci    * There are 4 tiles vertically, so the header is 8192 * 4 = 32768 bytes.
417bf215546Sopenharmony_ci    * This is already 4096-byte aligned.
418bf215546Sopenharmony_ci    *
419bf215546Sopenharmony_ci    * Each tile of superblock contains 128x128 pixels and each pixel is 4 bytes,
420bf215546Sopenharmony_ci    * so tiles are 65536 bytes, meaning the payload is 8 * 4 * 65536 = 2097152
421bf215546Sopenharmony_ci    * bytes.
422bf215546Sopenharmony_ci    *
423bf215546Sopenharmony_ci    * In total, the AFBC surface is 32768 + 2097152 = 2129920 bytes.
424bf215546Sopenharmony_ci    */
425bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].offset, 0);
426bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].row_stride, 8192);
427bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].afbc.header_size, 32768);
428bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].afbc.body_size, 2097152);
429bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].surface_stride, 2129920);
430bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].size, 2129920);
431bf215546Sopenharmony_ci}
432bf215546Sopenharmony_ci
433bf215546Sopenharmony_ciTEST(AFBCLayout, Linear16x16Minimal)
434bf215546Sopenharmony_ci{
435bf215546Sopenharmony_ci   uint64_t modifier = DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
436bf215546Sopenharmony_ci                        AFBC_FORMAT_MOD_SPARSE);
437bf215546Sopenharmony_ci
438bf215546Sopenharmony_ci   struct pan_image_layout l = {
439bf215546Sopenharmony_ci      .modifier = modifier,
440bf215546Sopenharmony_ci      .format = PIPE_FORMAT_R8_UNORM,
441bf215546Sopenharmony_ci      .width = 1,
442bf215546Sopenharmony_ci      .height = 1,
443bf215546Sopenharmony_ci      .depth = 1,
444bf215546Sopenharmony_ci      .nr_samples = 1,
445bf215546Sopenharmony_ci      .dim = MALI_TEXTURE_DIMENSION_2D,
446bf215546Sopenharmony_ci      .nr_slices = 1
447bf215546Sopenharmony_ci   };
448bf215546Sopenharmony_ci
449bf215546Sopenharmony_ci   ASSERT_TRUE(pan_image_layout_init(&l, NULL));
450bf215546Sopenharmony_ci
451bf215546Sopenharmony_ci   /* Image is 1x1 to test for correct alignment everywhere. */
452bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].offset, 0);
453bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].row_stride, 16);
454bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].afbc.header_size, 64);
455bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].afbc.body_size, 32 * 8);
456bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].surface_stride, 64 + (32 * 8));
457bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].size, 64 + (32 * 8));
458bf215546Sopenharmony_ci}
459bf215546Sopenharmony_ci
460bf215546Sopenharmony_ciTEST(AFBCLayout, Tiled16x16Minimal)
461bf215546Sopenharmony_ci{
462bf215546Sopenharmony_ci   uint64_t modifier = DRM_FORMAT_MOD_ARM_AFBC(AFBC_FORMAT_MOD_BLOCK_SIZE_16x16 |
463bf215546Sopenharmony_ci                        AFBC_FORMAT_MOD_TILED |
464bf215546Sopenharmony_ci                        AFBC_FORMAT_MOD_SPARSE);
465bf215546Sopenharmony_ci
466bf215546Sopenharmony_ci   struct pan_image_layout l = {
467bf215546Sopenharmony_ci      .modifier = modifier,
468bf215546Sopenharmony_ci      .format = PIPE_FORMAT_R8_UNORM,
469bf215546Sopenharmony_ci      .width = 1,
470bf215546Sopenharmony_ci      .height = 1,
471bf215546Sopenharmony_ci      .depth = 1,
472bf215546Sopenharmony_ci      .nr_samples = 1,
473bf215546Sopenharmony_ci      .dim = MALI_TEXTURE_DIMENSION_2D,
474bf215546Sopenharmony_ci      .nr_slices = 1
475bf215546Sopenharmony_ci   };
476bf215546Sopenharmony_ci
477bf215546Sopenharmony_ci   ASSERT_TRUE(pan_image_layout_init(&l, NULL));
478bf215546Sopenharmony_ci
479bf215546Sopenharmony_ci   /* Image is 1x1 to test for correct alignment everywhere. */
480bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].offset, 0);
481bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].row_stride, 16 * 8 * 8);
482bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].afbc.header_size, 4096);
483bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].afbc.body_size, 32 * 8 * 8 * 8);
484bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].surface_stride, 4096 + (32 * 8 * 8 * 8));
485bf215546Sopenharmony_ci   EXPECT_EQ(l.slices[0].size, 4096 + (32 * 8 * 8 * 8));
486bf215546Sopenharmony_ci}
487