diff --git a/src/freedreno/vulkan/tu_clear_blit.cc b/src/freedreno/vulkan/tu_clear_blit.cc index bd7252a0325..1486784fd4e 100644 --- a/src/freedreno/vulkan/tu_clear_blit.cc +++ b/src/freedreno/vulkan/tu_clear_blit.cc @@ -19,6 +19,7 @@ #include "tu_buffer.h" #include "tu_cmd_buffer.h" #include "tu_cs.h" +#include "tu_descriptor_set.h" #include "tu_formats.h" #include "tu_image.h" #include "tu_tracepoints.h" @@ -1087,10 +1088,11 @@ r3d_src_common(struct tu_cmd_buffer *cmd, memcpy(texture.map, tex_const, FDL6_TEX_CONST_DWORDS * 4); /* patch addresses for layer offset */ - *(uint64_t*) (texture.map + 4) += offset_base; - uint64_t ubwc_addr = (texture.map[7] | (uint64_t) texture.map[8] << 32) + offset_ubwc; - texture.map[7] = ubwc_addr; - texture.map[8] = ubwc_addr >> 32; + uint64_t addr = tu_desc_get_addr(texture.map); + tu_desc_set_addr(texture.map, addr + offset_base); + uint64_t ubwc_addr = tu_desc_get_ubwc(texture.map); + if (ubwc_addr) + tu_desc_set_ubwc(texture.map, ubwc_addr + offset_ubwc); texture.map[FDL6_TEX_CONST_DWORDS + 0] = A6XX_TEX_SAMP_0_XY_MAG(tu6_tex_filter(filter, false)) | @@ -1139,11 +1141,10 @@ r3d_src(struct tu_cmd_buffer *cmd, uint32_t desc[FDL6_TEX_CONST_DWORDS]; memcpy(desc, iview->descriptor, sizeof(desc)); - enum a6xx_format fmt = - (enum a6xx_format) pkt_field_get(A6XX_TEX_CONST_0_FMT, desc[0]); + enum a6xx_format fmt = tu_desc_get_format(desc); enum pipe_format src_format = iview->format; fixup_src_format(&src_format, dst_format, &fmt); - desc[0] = pkt_field_set(A6XX_TEX_CONST_0_FMT, desc[0], fmt); + tu_desc_set_format(desc, fmt); r3d_src_common(cmd, cs, desc, iview->layer_size * layer, @@ -1160,29 +1161,23 @@ r3d_src_buffer(struct tu_cmd_buffer *cmd, uint32_t width, uint32_t height, enum pipe_format dst_format) { - uint32_t desc[FDL6_TEX_CONST_DWORDS]; + uint32_t desc[FDL6_TEX_CONST_DWORDS] = {}; struct tu_native_format fmt = blit_format_texture(format, TILE6_LINEAR, false, false); enum a6xx_format color_format = fmt.fmt; fixup_src_format(&format, dst_format, &color_format); - desc[0] = - COND(util_format_is_srgb(format), A6XX_TEX_CONST_0_SRGB) | - A6XX_TEX_CONST_0_FMT(color_format) | - A6XX_TEX_CONST_0_SWAP(fmt.swap) | - A6XX_TEX_CONST_0_SWIZ_X(A6XX_TEX_X) | - A6XX_TEX_CONST_0_SWIZ_Y(A6XX_TEX_Y) | - A6XX_TEX_CONST_0_SWIZ_Z(A6XX_TEX_Z) | - A6XX_TEX_CONST_0_SWIZ_W(A6XX_TEX_W); - desc[1] = A6XX_TEX_CONST_1_WIDTH(width) | A6XX_TEX_CONST_1_HEIGHT(height); - desc[2] = - A6XX_TEX_CONST_2_PITCH(pitch) | - A6XX_TEX_CONST_2_TYPE(A6XX_TEX_2D); - desc[3] = 0; - desc[4] = va; - desc[5] = va >> 32; - for (uint32_t i = 6; i < FDL6_TEX_CONST_DWORDS; i++) - desc[i] = 0; + /* TODO are sRGB buffers a thing? */ + desc[0] = COND(util_format_is_srgb(format), A6XX_TEX_CONST_0_SRGB); + + tu_desc_set_dim(desc, width, height); + tu_desc_set_tex_line_offset(desc, pitch); + tu_desc_set_addr(desc, va); + tu_desc_set_depth(desc, 0); + tu_desc_set_format(desc, color_format); + tu_desc_set_swap(desc, fmt.swap); + tu_desc_set_swiz(desc, tu_swiz(X, Y, Z, W)); + tu_desc_set_type(desc, A6XX_TEX_2D); r3d_src_common(cmd, cs, desc, 0, 0, VK_FILTER_NEAREST); } @@ -1200,23 +1195,14 @@ r3d_src_depth(struct tu_cmd_buffer *cmd, memcpy(desc, iview->view.descriptor, sizeof(desc)); uint64_t va = iview->depth_base_addr; - desc[0] &= ~(A6XX_TEX_CONST_0_FMT__MASK | - A6XX_TEX_CONST_0_SWIZ_X__MASK | A6XX_TEX_CONST_0_SWIZ_Y__MASK | - A6XX_TEX_CONST_0_SWIZ_Z__MASK | A6XX_TEX_CONST_0_SWIZ_W__MASK | - A6XX_TEX_CONST_0_SWAP__MASK); - desc[0] |= A6XX_TEX_CONST_0_FMT(FMT6_32_FLOAT) | - A6XX_TEX_CONST_0_SWIZ_X(A6XX_TEX_X) | - A6XX_TEX_CONST_0_SWIZ_Y(A6XX_TEX_Y) | - A6XX_TEX_CONST_0_SWIZ_Z(A6XX_TEX_Z) | - A6XX_TEX_CONST_0_SWIZ_W(A6XX_TEX_W); - desc[2] = - A6XX_TEX_CONST_2_PITCH(iview->depth_pitch) | - A6XX_TEX_CONST_2_TYPE(A6XX_TEX_2D); - desc[3] = - pkt_field_set(A6XX_TEX_CONST_3_ARRAY_PITCH, iview->view.descriptor[3], - iview->depth_layer_size); - desc[4] = va; - desc[5] = va >> 32; + tu_desc_set_min_line_offset(desc, 0); + tu_desc_set_tex_line_offset(desc, iview->depth_pitch); + tu_desc_set_array_slice_offset(desc, iview->depth_layer_size); + tu_desc_set_addr(desc, va); + tu_desc_set_depth(desc, 0); + tu_desc_set_format(desc, FMT6_32_FLOAT); + tu_desc_set_swiz(desc, tu_swiz(X, Y, Z, W)); + tu_desc_set_type(desc, A6XX_TEX_2D); r3d_src_common(cmd, cs, desc, iview->depth_layer_size * layer, @@ -1237,23 +1223,17 @@ r3d_src_stencil(struct tu_cmd_buffer *cmd, memcpy(desc, iview->view.descriptor, sizeof(desc)); uint64_t va = iview->stencil_base_addr; - desc[0] &= ~(A6XX_TEX_CONST_0_FMT__MASK | - A6XX_TEX_CONST_0_SWIZ_X__MASK | A6XX_TEX_CONST_0_SWIZ_Y__MASK | - A6XX_TEX_CONST_0_SWIZ_Z__MASK | A6XX_TEX_CONST_0_SWIZ_W__MASK | - A6XX_TEX_CONST_0_SWAP__MASK); - desc[0] |= A6XX_TEX_CONST_0_FMT(FMT6_8_UINT) | - A6XX_TEX_CONST_0_SWIZ_X(A6XX_TEX_X) | - A6XX_TEX_CONST_0_SWIZ_Y(A6XX_TEX_Y) | - A6XX_TEX_CONST_0_SWIZ_Z(A6XX_TEX_Z) | - A6XX_TEX_CONST_0_SWIZ_W(A6XX_TEX_W); - desc[2] = - A6XX_TEX_CONST_2_PITCH(iview->stencil_pitch) | - A6XX_TEX_CONST_2_TYPE(A6XX_TEX_2D); - desc[3] = A6XX_TEX_CONST_3_ARRAY_PITCH(iview->stencil_layer_size); - desc[4] = va; - desc[5] = va >> 32; - for (unsigned i = 6; i < FDL6_TEX_CONST_DWORDS; i++) - desc[i] = 0; + /* Separate stencil is linear even if depth is not: */ + tu_desc_set_ubwc(desc, 0); + + tu_desc_set_min_line_offset(desc, 0); + tu_desc_set_tex_line_offset(desc, iview->stencil_pitch); + tu_desc_set_array_slice_offset(desc, iview->stencil_layer_size); + tu_desc_set_addr(desc, va); + tu_desc_set_depth(desc, 0); + tu_desc_set_format(desc, FMT6_8_UINT); + tu_desc_set_swiz(desc, tu_swiz(X, Y, Z, W)); + tu_desc_set_type(desc, A6XX_TEX_2D); r3d_src_common(cmd, cs, desc, iview->stencil_layer_size * layer, 0, VK_FILTER_NEAREST); @@ -1282,21 +1262,16 @@ r3d_src_load(struct tu_cmd_buffer *cmd, else tex_format = FMT6_8_8_8_8_UNORM; - desc[0] = pkt_field_set(A6XX_TEX_CONST_0_FMT, desc[0], tex_format); + tu_desc_set_format(desc, tex_format); } /* When loading/storing GMEM we always load the full image and don't do any * swizzling or swapping, that's done in the draw when reading/writing * GMEM, so we need to fixup the swizzle and swap. */ - desc[0] &= ~(A6XX_TEX_CONST_0_SWIZ_X__MASK | A6XX_TEX_CONST_0_SWIZ_Y__MASK | - A6XX_TEX_CONST_0_SWIZ_Z__MASK | A6XX_TEX_CONST_0_SWIZ_W__MASK); if (override_swap) - desc[0] &= ~A6XX_TEX_CONST_0_SWAP__MASK; - desc[0] |= A6XX_TEX_CONST_0_SWIZ_X(A6XX_TEX_X) | - A6XX_TEX_CONST_0_SWIZ_Y(A6XX_TEX_Y) | - A6XX_TEX_CONST_0_SWIZ_Z(A6XX_TEX_Z) | - A6XX_TEX_CONST_0_SWIZ_W(A6XX_TEX_W); + tu_desc_set_swap(desc, WZYX); + tu_desc_set_swiz(desc, tu_swiz(X, Y, Z, W)); r3d_src_common(cmd, cs, desc, iview->view.layer_size * layer, @@ -1342,42 +1317,37 @@ r3d_src_gmem(struct tu_cmd_buffer *cmd, iview->view.is_mutable, true).fmt; fixup_src_format(&format, dst_format, &fmt); - /* patch the format so that depth/stencil get the right format and swizzle */ - desc[0] &= ~(A6XX_TEX_CONST_0_FMT__MASK | - A6XX_TEX_CONST_0_SWIZ_X__MASK | A6XX_TEX_CONST_0_SWIZ_Y__MASK | - A6XX_TEX_CONST_0_SWIZ_Z__MASK | A6XX_TEX_CONST_0_SWIZ_W__MASK); - desc[0] |= A6XX_TEX_CONST_0_FMT(fmt) | - A6XX_TEX_CONST_0_SWIZ_X(A6XX_TEX_X) | - A6XX_TEX_CONST_0_SWIZ_Y(A6XX_TEX_Y) | - A6XX_TEX_CONST_0_SWIZ_Z(A6XX_TEX_Z) | - A6XX_TEX_CONST_0_SWIZ_W(A6XX_TEX_W); - /* patched for gmem */ - desc[0] = pkt_field_set(A6XX_TEX_CONST_0_TILE_MODE, desc[0], TILE6_2); + tu_desc_set_tile_mode(desc, TILE6_2); + if (!iview->view.is_mutable) - desc[0] = pkt_field_set(A6XX_TEX_CONST_0_SWAP, desc[0], WZYX); + tu_desc_set_swap(desc, WZYX); /* If FDM offset is used, the last row and column extend beyond the * framebuffer but are shifted over when storing. Expand the width and * height to account for that. */ if (tu_enable_fdm_offset(cmd)) { - uint32_t width = pkt_field_get(A6XX_TEX_CONST_1_WIDTH, desc[1]); - uint32_t height = pkt_field_get(A6XX_TEX_CONST_1_HEIGHT, desc[1]); + uint32_t width, height; + + tu_desc_get_dim(desc, &width, &height); width += cmd->state.tiling->tile0.width; height += cmd->state.tiling->tile0.height; - desc[1] = pkt_field_set(A6XX_TEX_CONST_1_WIDTH, desc[1], width); - desc[1] = pkt_field_set(A6XX_TEX_CONST_1_HEIGHT, desc[1], height); + tu_desc_set_dim(desc, width, height); } - desc[2] = - A6XX_TEX_CONST_2_TYPE(A6XX_TEX_2D) | - A6XX_TEX_CONST_2_PITCH(cmd->state.tiling->tile0.width * cpp); - desc[3] = 0; - desc[4] = cmd->device->physical_device->gmem_base + gmem_offset; - desc[5] = A6XX_TEX_CONST_5_DEPTH(1); - for (unsigned i = 6; i < FDL6_TEX_CONST_DWORDS; i++) - desc[i] = 0; + tu_desc_set_tile_all(desc, false); + tu_desc_set_ubwc(desc, 0); + tu_desc_set_min_line_offset(desc, 0); + tu_desc_set_tex_line_offset(desc, cmd->state.tiling->tile0.width * cpp); + tu_desc_set_array_slice_offset(desc, 0); + tu_desc_set_depth(desc, 1); + tu_desc_set_addr(desc, cmd->device->physical_device->gmem_base + gmem_offset); + + /* patch the format so that depth/stencil get the right format and swizzle */ + tu_desc_set_format(desc, fmt); + tu_desc_set_swiz(desc, tu_swiz(X, Y, Z, W)); + tu_desc_set_type(desc, A6XX_TEX_2D); r3d_src_common(cmd, cs, desc, 0, 0, VK_FILTER_NEAREST); } diff --git a/src/freedreno/vulkan/tu_cmd_buffer.cc b/src/freedreno/vulkan/tu_cmd_buffer.cc index 658520e6b9c..0f5fda9400c 100644 --- a/src/freedreno/vulkan/tu_cmd_buffer.cc +++ b/src/freedreno/vulkan/tu_cmd_buffer.cc @@ -2647,13 +2647,12 @@ tu_emit_input_attachments(struct tu_cmd_buffer *cmd, * of a renderpass. We have to patch the descriptor to make it compatible * with how it is sampled in shader. */ - enum a6xx_tex_type tex_type = - (enum a6xx_tex_type) pkt_field_get(A6XX_TEX_CONST_2_TYPE, dst[2]); + enum a6xx_tex_type tex_type = tu_desc_get_type(dst); if (tex_type == A6XX_TEX_CUBE) { - dst[2] = pkt_field_set(A6XX_TEX_CONST_2_TYPE, dst[2], A6XX_TEX_2D); + tu_desc_set_type(dst, A6XX_TEX_2D); - uint32_t depth = pkt_field_get(A6XX_TEX_CONST_5_DEPTH, dst[5]); - dst[5] = pkt_field_set(A6XX_TEX_CONST_5_DEPTH, dst[5], depth * 6); + uint32_t depth = tu_desc_get_depth(dst); + tu_desc_set_depth(dst, depth * 6); } if (i % 2 == 1 && att->format == VK_FORMAT_D24_UNORM_S8_UINT) { @@ -2663,33 +2662,23 @@ tu_emit_input_attachments(struct tu_cmd_buffer *cmd, * Also we clear swap to WZYX. This is because the view might have * picked XYZW to work better with border colors. */ - dst[0] &= ~(A6XX_TEX_CONST_0_FMT__MASK | - A6XX_TEX_CONST_0_SWAP__MASK | - A6XX_TEX_CONST_0_SWIZ_X__MASK | A6XX_TEX_CONST_0_SWIZ_Y__MASK | - A6XX_TEX_CONST_0_SWIZ_Z__MASK | A6XX_TEX_CONST_0_SWIZ_W__MASK); + tu_desc_set_swap(dst, WZYX); if (!cmd->device->physical_device->info->props.has_z24uint_s8uint) { - dst[0] |= A6XX_TEX_CONST_0_FMT(FMT6_8_8_8_8_UINT) | - A6XX_TEX_CONST_0_SWIZ_X(A6XX_TEX_W) | - A6XX_TEX_CONST_0_SWIZ_Y(A6XX_TEX_ZERO) | - A6XX_TEX_CONST_0_SWIZ_Z(A6XX_TEX_ZERO) | - A6XX_TEX_CONST_0_SWIZ_W(A6XX_TEX_ONE); + tu_desc_set_format(dst, FMT6_8_8_8_8_UINT); + tu_desc_set_swiz(dst, tu_swiz(W, 0, 0, 1)); } else { - dst[0] |= A6XX_TEX_CONST_0_FMT(FMT6_Z24_UINT_S8_UINT) | - A6XX_TEX_CONST_0_SWIZ_X(A6XX_TEX_Y) | - A6XX_TEX_CONST_0_SWIZ_Y(A6XX_TEX_ZERO) | - A6XX_TEX_CONST_0_SWIZ_Z(A6XX_TEX_ZERO) | - A6XX_TEX_CONST_0_SWIZ_W(A6XX_TEX_ONE); + tu_desc_set_format(dst, FMT6_Z24_UINT_S8_UINT); + tu_desc_set_swiz(dst, tu_swiz(Y, 0, 0, 1)); } } if (i % 2 == 1 && att->format == VK_FORMAT_D32_SFLOAT_S8_UINT) { - dst[0] = pkt_field_set(A6XX_TEX_CONST_0_FMT, dst[0], FMT6_8_UINT); - dst[2] = pkt_field_set(A6XX_TEX_CONST_2_PITCHALIGN, dst[2], 0); - dst[2] = pkt_field_set(A6XX_TEX_CONST_2_PITCH, dst[2], - iview->stencil_pitch); - dst[3] = 0; - dst[4] = iview->stencil_base_addr; - dst[5] = (dst[5] & 0xffff) | iview->stencil_base_addr >> 32; + tu_desc_set_format(dst, FMT6_8_UINT); + tu_desc_set_min_line_offset(dst, 0); + tu_desc_set_tex_line_offset(dst, iview->stencil_pitch); + tu_desc_set_addr(dst, iview->stencil_base_addr); + tu_desc_set_array_slice_offset(dst, 0); + tu_desc_set_ubwc(dst, 0); cpp = att->samples; gmem_offset = att->gmem_offset_stencil[cmd->state.gmem_layout]; @@ -2705,41 +2694,40 @@ tu_emit_input_attachments(struct tu_cmd_buffer *cmd, } /* patched for gmem */ - dst[0] = pkt_field_set(A6XX_TEX_CONST_0_TILE_MODE, dst[0], TILE6_2); + tu_desc_set_tile_mode(dst, TILE6_2); + if (!iview->view.is_mutable) - dst[0] = pkt_field_set(A6XX_TEX_CONST_0_SWAP, dst[0], WZYX); + tu_desc_set_swap(dst, WZYX); /* If FDM offset is used, the last row and column extend beyond the * framebuffer but are shifted over when storing. Expand the width and * height to account for that. */ if (tu_enable_fdm_offset(cmd)) { - uint32_t width = pkt_field_get(A6XX_TEX_CONST_1_WIDTH, dst[1]); - uint32_t height = pkt_field_get(A6XX_TEX_CONST_1_HEIGHT, dst[1]); + uint32_t width, height; + + tu_desc_get_dim(dst, &width, &height); width += cmd->state.tiling->tile0.width; height += cmd->state.tiling->tile0.height; - dst[1] = pkt_field_set(A6XX_TEX_CONST_1_WIDTH, dst[1], width); - dst[1] = pkt_field_set(A6XX_TEX_CONST_1_HEIGHT, dst[1], height); + tu_desc_set_dim(dst, width, height); } - dst[2] = - A6XX_TEX_CONST_2_TYPE(A6XX_TEX_2D) | - A6XX_TEX_CONST_2_PITCH(tiling->tile0.width * cpp); + tu_desc_set_type(dst, A6XX_TEX_2D); + tu_desc_set_min_line_offset(dst, 0); + tu_desc_set_tex_line_offset(dst, tiling->tile0.width * cpp); + tu_desc_set_ubwc(dst, 0); /* Note: it seems the HW implicitly calculates the array pitch, except * when rendering to sysmem (i.e. in a custom resolve subpass). We only * guarantee the pitch is valid when there is more than 1 layer, so skip * emitting it otherwise to avoid asserts. */ if (layers > 1) { - dst[3] = A6XX_TEX_CONST_3_ARRAY_PITCH(tiling->tile0.width * - tiling->tile0.height * cpp); + uint32_t array_pitch = tiling->tile0.width * tiling->tile0.height * cpp; + tu_desc_set_array_slice_offset(dst, array_pitch); } else { - dst[3] = 0; + tu_desc_set_array_slice_offset(dst, 0); } - dst[4] = cmd->device->physical_device->gmem_base + gmem_offset; - dst[5] &= A6XX_TEX_CONST_5_DEPTH__MASK; - for (unsigned i = 6; i < FDL6_TEX_CONST_DWORDS; i++) - dst[i] = 0; + tu_desc_set_addr(dst, cmd->device->physical_device->gmem_base + gmem_offset); memcpy(&texture.map[i * FDL6_TEX_CONST_DWORDS], dst, sizeof(dst)); } @@ -4759,16 +4747,14 @@ tu_bind_descriptor_sets(struct tu_cmd_buffer *cmd, for (unsigned i = 0; i < binding->size / (4 * FDL6_TEX_CONST_DWORDS); i++, dst_desc += FDL6_TEX_CONST_DWORDS) { - /* Note: A6XX_TEX_CONST_5_DEPTH is always 0 */ - uint64_t va = dst_desc[4] | ((uint64_t)dst_desc[5] << 32); + uint64_t va = tu_desc_get_addr(dst_desc); uint32_t desc_offset = pkt_field_get( A6XX_TEX_CONST_2_STARTOFFSETTEXELS, dst_desc[2]); /* Use descriptor's format to determine the shift amount * that's to be used on the offset value. */ - uint32_t format = - pkt_field_get(A6XX_TEX_CONST_0_FMT, dst_desc[0]); + enum a6xx_format format = tu_desc_get_format(dst_desc); unsigned offset_shift; switch (format) { case FMT6_16_UINT: @@ -4787,8 +4773,7 @@ tu_bind_descriptor_sets(struct tu_cmd_buffer *cmd, va += offset; unsigned new_offset = (va & 0x3f) >> offset_shift; va &= ~0x3full; - dst_desc[4] = va; - dst_desc[5] = va >> 32; + tu_desc_set_addr(dst_desc, va); dst_desc[2] = pkt_field_set(A6XX_TEX_CONST_2_STARTOFFSETTEXELS, dst_desc[2], new_offset); diff --git a/src/freedreno/vulkan/tu_descriptor_set.h b/src/freedreno/vulkan/tu_descriptor_set.h index 31041856e88..3e757367911 100644 --- a/src/freedreno/vulkan/tu_descriptor_set.h +++ b/src/freedreno/vulkan/tu_descriptor_set.h @@ -13,6 +13,9 @@ #include "tu_sampler.h" #include "util/vma.h" +#include "common/freedreno_pm4.h" +#include "fdl/fd6_format_table.h" + /* The hardware supports up to 8 descriptor sets since A7XX. * Note: This is the maximum across generations, not the maximum for a * particular generation so it should only be used for allocation. @@ -239,6 +242,174 @@ tu_immutable_ycbcr_samplers(const struct tu_descriptor_set_layout *set, binding->ycbcr_samplers_offset); } +/* + * Helpers for modifying descriptors: + */ + #define tu_swiz(x, y, z, w) (uint8_t[]){ PIPE_SWIZZLE_ ##x, PIPE_SWIZZLE_ ##y, PIPE_SWIZZLE_ ##z, PIPE_SWIZZLE_ ##w } +template +static inline void +tu_desc_set_swiz(uint32_t *desc, const uint8_t *swiz) +{ + desc[0] = pkt_field_set(A6XX_TEX_CONST_0_SWIZ_X, desc[0], fdl6_swiz(swiz[0])); + desc[0] = pkt_field_set(A6XX_TEX_CONST_0_SWIZ_Y, desc[0], fdl6_swiz(swiz[1])); + desc[0] = pkt_field_set(A6XX_TEX_CONST_0_SWIZ_Z, desc[0], fdl6_swiz(swiz[2])); + desc[0] = pkt_field_set(A6XX_TEX_CONST_0_SWIZ_W, desc[0], fdl6_swiz(swiz[3])); +} + +template +static inline enum a6xx_format +tu_desc_get_format(uint32_t *desc) +{ + return (enum a6xx_format)pkt_field_get(A6XX_TEX_CONST_0_FMT, desc[0]); +} + +template +static inline void +tu_desc_set_format(uint32_t *desc, enum a6xx_format fmt) +{ + desc[0] = pkt_field_set(A6XX_TEX_CONST_0_FMT, desc[0], fmt); +} + +template +static inline void +tu_desc_set_swap(uint32_t *desc, enum a3xx_color_swap swap) +{ + desc[0] = pkt_field_set(A6XX_TEX_CONST_0_SWAP, desc[0], swap); +} + +template +static inline void +tu_desc_set_tile_mode(uint32_t *desc, enum a6xx_tile_mode tile_mode) +{ + desc[0] = pkt_field_set(A6XX_TEX_CONST_0_TILE_MODE, desc[0], tile_mode); +} + +template +static inline void +tu_desc_set_tile_all(uint32_t *desc, bool tile_all) +{ + if (tile_all) { + desc[3] |= A6XX_TEX_CONST_3_TILE_ALL; + } else { + desc[3] &= ~A6XX_TEX_CONST_3_TILE_ALL; + } +} + +template +static inline enum a6xx_tex_type +tu_desc_get_type(uint32_t *desc) +{ + return (enum a6xx_tex_type)pkt_field_get(A6XX_TEX_CONST_2_TYPE, desc[2]); +} + +template +static inline void +tu_desc_set_type(uint32_t *desc, enum a6xx_tex_type type) +{ + desc[2] = pkt_field_set(A6XX_TEX_CONST_2_TYPE, desc[2], type); +} + +template +static inline void +tu_desc_get_dim(uint32_t *desc, uint32_t *width, uint32_t *height) +{ + *width = pkt_field_get(A6XX_TEX_CONST_1_WIDTH, desc[1]); + *height = pkt_field_get(A6XX_TEX_CONST_1_HEIGHT, desc[1]); +} + +template +static inline void +tu_desc_set_dim(uint32_t *desc, uint32_t width, uint32_t height) +{ + desc[1] = pkt_field_set(A6XX_TEX_CONST_1_WIDTH, desc[1], width); + desc[1] = pkt_field_set(A6XX_TEX_CONST_1_HEIGHT, desc[1], height); +} + +template +static inline uint32_t +tu_desc_get_depth(uint32_t *desc) +{ + return pkt_field_get(A6XX_TEX_CONST_5_DEPTH, desc[5]); +} + +template +static inline void +tu_desc_set_depth(uint32_t *desc, uint32_t depth) +{ + desc[5] = pkt_field_set(A6XX_TEX_CONST_5_DEPTH, desc[5], depth); +} + +template +static inline void +tu_desc_set_struct_size_texels(uint32_t *desc, uint32_t struct_size_texels) +{ + desc[2] = pkt_field_set(A6XX_TEX_CONST_2_STRUCTSIZETEXELS, desc[2], struct_size_texels); +} + +template +static inline void +tu_desc_set_min_line_offset(uint32_t *desc, uint32_t min_line_offset) +{ + desc[2] = pkt_field_set(A6XX_TEX_CONST_2_PITCHALIGN, desc[2], min_line_offset); +} + +template +static inline void +tu_desc_set_tex_line_offset(uint32_t *desc, uint32_t tex_line_offset) +{ + desc[2] = pkt_field_set(A6XX_TEX_CONST_2_PITCH, desc[2], tex_line_offset); +} + +template +static inline void +tu_desc_set_array_slice_offset(uint32_t *desc, uint32_t array_slice_offset) +{ + desc[3] = pkt_field_set(A6XX_TEX_CONST_3_ARRAY_PITCH, desc[3], array_slice_offset); +} + +template +static inline uint64_t +tu_desc_get_addr(uint32_t *desc) +{ + uint64_t addr = desc[4]; + addr |= (uint64_t)(desc[5] & 0xffff) << 32; + return addr; +} + +template +static inline void +tu_desc_set_addr(uint32_t *desc, uint64_t addr) +{ + desc[4] = addr; + desc[5] = (desc[5] & ~0xffff) | addr >> 32; +} + +template +static inline uint64_t +tu_desc_get_ubwc(uint32_t *desc) +{ + if (desc[3] & A6XX_TEX_CONST_3_FLAG) { + uint64_t addr = desc[7]; + addr |= (uint64_t)(desc[8] & 0xffff) << 32; + return addr; + } else { + return 0; + } +} + +template +static inline void +tu_desc_set_ubwc(uint32_t *desc, uint64_t addr) +{ + if (addr) { + desc[7] = addr; + desc[8] = (desc[8] & 0xffff) | addr >> 32; + desc[3] |= A6XX_TEX_CONST_3_FLAG; + } else { + desc[3] &= ~A6XX_TEX_CONST_3_FLAG; + } +} + #endif /* TU_DESCRIPTOR_SET_H */