+
+ surf->u.gfx9.display_dcc_size = surf->dcc_size;
+ surf->u.gfx9.display_dcc_alignment = surf->dcc_alignment;
+ surf->u.gfx9.display_dcc_pitch_max = dout.pitch - 1;
+
+ /* Compute displayable DCC. */
+ if (in->flags.display &&
+ surf->num_dcc_levels &&
+ info->use_display_dcc_with_retile_blit) {
+ /* Compute displayable DCC info. */
+ din.dccKeyFlags.pipeAligned = 0;
+ din.dccKeyFlags.rbAligned = 0;
+
+ assert(din.numSlices == 1);
+ assert(din.numMipLevels == 1);
+ assert(din.numFrags == 1);
+ assert(surf->tile_swizzle == 0);
+ assert(surf->u.gfx9.dcc.pipe_aligned ||
+ surf->u.gfx9.dcc.rb_aligned);
+
+ ret = Addr2ComputeDccInfo(addrlib, &din, &dout);
+ if (ret != ADDR_OK)
+ return ret;
+
+ surf->u.gfx9.display_dcc_size = dout.dccRamSize;
+ surf->u.gfx9.display_dcc_alignment = dout.dccRamBaseAlign;
+ surf->u.gfx9.display_dcc_pitch_max = dout.pitch - 1;
+ assert(surf->u.gfx9.display_dcc_size <= surf->dcc_size);
+
+ /* Compute address mapping from non-displayable to displayable DCC. */
+ ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT addrin = {};
+ addrin.size = sizeof(addrin);
+ addrin.colorFlags.color = 1;
+ addrin.swizzleMode = din.swizzleMode;
+ addrin.resourceType = din.resourceType;
+ addrin.bpp = din.bpp;
+ addrin.unalignedWidth = din.unalignedWidth;
+ addrin.unalignedHeight = din.unalignedHeight;
+ addrin.numSlices = 1;
+ addrin.numMipLevels = 1;
+ addrin.numFrags = 1;
+
+ ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT addrout = {};
+ addrout.size = sizeof(addrout);
+
+ surf->u.gfx9.dcc_retile_num_elements =
+ DIV_ROUND_UP(in->width, dout.compressBlkWidth) *
+ DIV_ROUND_UP(in->height, dout.compressBlkHeight) * 2;
+ /* Align the size to 4 (for the compute shader). */
+ surf->u.gfx9.dcc_retile_num_elements =
+ align(surf->u.gfx9.dcc_retile_num_elements, 4);
+
+ surf->u.gfx9.dcc_retile_map =
+ malloc(surf->u.gfx9.dcc_retile_num_elements * 4);
+ if (!surf->u.gfx9.dcc_retile_map)
+ return ADDR_OUTOFMEMORY;
+
+ unsigned index = 0;
+ surf->u.gfx9.dcc_retile_use_uint16 = true;
+
+ for (unsigned y = 0; y < in->height; y += dout.compressBlkHeight) {
+ addrin.y = y;
+
+ for (unsigned x = 0; x < in->width; x += dout.compressBlkWidth) {
+ addrin.x = x;
+
+ /* Compute src DCC address */
+ addrin.dccKeyFlags.pipeAligned = surf->u.gfx9.dcc.pipe_aligned;
+ addrin.dccKeyFlags.rbAligned = surf->u.gfx9.dcc.rb_aligned;
+ addrout.addr = 0;
+
+ ret = Addr2ComputeDccAddrFromCoord(addrlib, &addrin, &addrout);
+ if (ret != ADDR_OK)
+ return ret;
+
+ surf->u.gfx9.dcc_retile_map[index * 2] = addrout.addr;
+ if (addrout.addr > UINT16_MAX)
+ surf->u.gfx9.dcc_retile_use_uint16 = false;
+
+ /* Compute dst DCC address */
+ addrin.dccKeyFlags.pipeAligned = 0;
+ addrin.dccKeyFlags.rbAligned = 0;
+ addrout.addr = 0;
+
+ ret = Addr2ComputeDccAddrFromCoord(addrlib, &addrin, &addrout);
+ if (ret != ADDR_OK)
+ return ret;
+
+ surf->u.gfx9.dcc_retile_map[index * 2 + 1] = addrout.addr;
+ if (addrout.addr > UINT16_MAX)
+ surf->u.gfx9.dcc_retile_use_uint16 = false;
+
+ assert(index * 2 + 1 < surf->u.gfx9.dcc_retile_num_elements);
+ index++;
+ }
+ }
+ /* Fill the remaining pairs with the last one (for the compute shader). */
+ for (unsigned i = index * 2; i < surf->u.gfx9.dcc_retile_num_elements; i++)
+ surf->u.gfx9.dcc_retile_map[i] = surf->u.gfx9.dcc_retile_map[i - 2];
+ }