radv/gfx10: add gfx10_make_texture_descriptor
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Tue, 25 Jun 2019 07:23:04 +0000 (09:23 +0200)
committerBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Sun, 7 Jul 2019 15:03:38 +0000 (17:03 +0200)
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
src/amd/vulkan/radv_image.c

index e92aef3ba30f0ffb53a46254575d8680b53e7148..cad564f5835f2a24060c81caf5d46fc081a57e19 100644 (file)
@@ -572,7 +572,134 @@ static unsigned gfx9_border_color_swizzle(const enum vk_swizzle swizzle[4])
 }
 
 /**
- * Build the sampler view descriptor for a texture.
+ * Build the sampler view descriptor for a texture (GFX10).
+ */
+static void
+gfx10_make_texture_descriptor(struct radv_device *device,
+                          struct radv_image *image,
+                          bool is_storage_image,
+                          VkImageViewType view_type,
+                          VkFormat vk_format,
+                          const VkComponentMapping *mapping,
+                          unsigned first_level, unsigned last_level,
+                          unsigned first_layer, unsigned last_layer,
+                          unsigned width, unsigned height, unsigned depth,
+                          uint32_t *state,
+                          uint32_t *fmask_state)
+{
+       const struct vk_format_description *desc;
+       enum vk_swizzle swizzle[4];
+       unsigned img_format;
+       unsigned type;
+
+       desc = vk_format_description(vk_format);
+       img_format = gfx10_format_table[vk_format].img_format;
+
+       if (desc->colorspace == VK_FORMAT_COLORSPACE_ZS) {
+               const unsigned char swizzle_xxxx[4] = {0, 0, 0, 0};
+               vk_format_compose_swizzles(mapping, swizzle_xxxx, swizzle);
+       } else {
+               vk_format_compose_swizzles(mapping, desc->swizzle, swizzle);
+       }
+
+       type = radv_tex_dim(image->type, view_type, image->info.array_size, image->info.samples,
+                           is_storage_image, device->physical_device->rad_info.chip_class >= GFX9);
+       if (type == V_008F1C_SQ_RSRC_IMG_1D_ARRAY) {
+               height = 1;
+               depth = image->info.array_size;
+       } else if (type == V_008F1C_SQ_RSRC_IMG_2D_ARRAY ||
+                  type == V_008F1C_SQ_RSRC_IMG_2D_MSAA_ARRAY) {
+               if (view_type != VK_IMAGE_VIEW_TYPE_3D)
+                       depth = image->info.array_size;
+       } else if (type == V_008F1C_SQ_RSRC_IMG_CUBE)
+               depth = image->info.array_size / 6;
+
+       state[0] = 0;
+       state[1] = S_00A004_FORMAT(img_format) |
+                  S_00A004_WIDTH_LO(width - 1);
+       state[2] = S_00A008_WIDTH_HI((width - 1) >> 2) |
+                  S_00A008_HEIGHT(height - 1) |
+                  S_00A008_RESOURCE_LEVEL(1);
+       state[3] = S_00A00C_DST_SEL_X(radv_map_swizzle(swizzle[0])) |
+                  S_00A00C_DST_SEL_Y(radv_map_swizzle(swizzle[1])) |
+                  S_00A00C_DST_SEL_Z(radv_map_swizzle(swizzle[2])) |
+                  S_00A00C_DST_SEL_W(radv_map_swizzle(swizzle[3])) |
+                  S_00A00C_BASE_LEVEL(image->info.samples > 1 ?
+                                       0 : first_level) |
+                  S_00A00C_LAST_LEVEL(image->info.samples > 1 ?
+                                       util_logbase2(image->info.samples) :
+                                       last_level) |
+                  S_00A00C_BC_SWIZZLE(gfx9_border_color_swizzle(swizzle)) |
+                  S_00A00C_TYPE(type);
+       /* Depth is the the last accessible layer on gfx9+. The hw doesn't need
+        * to know the total number of layers.
+        */
+       state[4] = S_00A010_DEPTH(type == V_008F1C_SQ_RSRC_IMG_3D ? depth - 1 : last_layer) |
+                  S_00A010_BASE_ARRAY(first_layer);
+       state[5] = S_00A014_ARRAY_PITCH(!!(type == V_008F1C_SQ_RSRC_IMG_3D)) |
+                  S_00A014_MAX_MIP(image->info.samples > 1 ?
+                                   util_logbase2(image->info.samples) :
+                                   image->info.levels - 1) |
+                  S_00A014_PERF_MOD(4);
+       state[6] = 0;
+       state[7] = 0;
+
+       if (radv_dcc_enabled(image, first_level)) {
+               unsigned swap = radv_translate_colorswap(vk_format, FALSE);
+
+               state[6] |= S_00A018_MAX_UNCOMPRESSED_BLOCK_SIZE(V_028C78_MAX_BLOCK_SIZE_256B) |
+                           S_00A018_MAX_COMPRESSED_BLOCK_SIZE(V_028C78_MAX_BLOCK_SIZE_128B) |
+                           S_00A018_ALPHA_IS_ON_MSB(swap <= 1);
+       }
+
+       /* Initialize the sampler view for FMASK. */
+       if (radv_image_has_fmask(image)) {
+               uint64_t gpu_address = radv_buffer_get_va(image->bo);
+               uint32_t format;
+               uint64_t va;
+
+               assert(image->plane_count == 1);
+
+               va = gpu_address + image->offset + image->fmask.offset;
+
+               switch (image->info.samples) {
+               case 2:
+                       format = V_008F0C_IMG_FORMAT_FMASK8_S2_F2;
+                       break;
+               case 4:
+                       format = V_008F0C_IMG_FORMAT_FMASK8_S4_F4;
+                       break;
+               case 8:
+                       format = V_008F0C_IMG_FORMAT_FMASK32_S8_F8;
+                       break;
+               default:
+                       unreachable("invalid nr_samples");
+               }
+
+               fmask_state[0] = (va >> 8) | image->planes[0].surface.fmask_tile_swizzle;
+               fmask_state[1] = S_00A004_BASE_ADDRESS_HI(va >> 40) |
+                                S_00A004_FORMAT(format) |
+                                S_00A004_WIDTH_LO(width - 1);
+               fmask_state[2] = S_00A008_WIDTH_HI((width - 1) >> 2) |
+                                S_00A008_HEIGHT(height - 1) |
+                                S_00A008_RESOURCE_LEVEL(1);
+               fmask_state[3] = S_00A00C_DST_SEL_X(V_008F1C_SQ_SEL_X) |
+                                S_00A00C_DST_SEL_Y(V_008F1C_SQ_SEL_X) |
+                                S_00A00C_DST_SEL_Z(V_008F1C_SQ_SEL_X) |
+                                S_00A00C_DST_SEL_W(V_008F1C_SQ_SEL_X) |
+                                S_00A00C_SW_MODE(image->planes[0].surface.u.gfx9.fmask.swizzle_mode) |
+                                S_00A00C_TYPE(radv_tex_dim(image->type, view_type, image->info.array_size, 0, false, false));
+               fmask_state[4] = S_00A010_DEPTH(last_layer) |
+                                S_00A010_BASE_ARRAY(first_layer);
+               fmask_state[5] = 0;
+               fmask_state[6] = S_00A018_META_PIPE_ALIGNED(image->planes[0].surface.u.gfx9.cmask.pipe_aligned);
+               fmask_state[7] = 0;
+       } else if (fmask_state)
+               memset(fmask_state, 0, 8 * 4);
+}
+
+/**
+ * Build the sampler view descriptor for a texture (SI-GFX9)
  */
 static void
 si_make_texture_descriptor(struct radv_device *device,
@@ -782,6 +909,36 @@ si_make_texture_descriptor(struct radv_device *device,
                memset(fmask_state, 0, 8 * 4);
 }
 
+static void
+radv_make_texture_descriptor(struct radv_device *device,
+                            struct radv_image *image,
+                            bool is_storage_image,
+                            VkImageViewType view_type,
+                            VkFormat vk_format,
+                            const VkComponentMapping *mapping,
+                            unsigned first_level, unsigned last_level,
+                            unsigned first_layer, unsigned last_layer,
+                            unsigned width, unsigned height, unsigned depth,
+                            uint32_t *state,
+                            uint32_t *fmask_state)
+{
+       if (device->physical_device->rad_info.chip_class >= GFX10) {
+               gfx10_make_texture_descriptor(device, image, is_storage_image,
+                                             view_type, vk_format, mapping,
+                                             first_level, last_level,
+                                             first_layer, last_layer,
+                                             width, height, depth,
+                                             state, fmask_state);
+       } else {
+               si_make_texture_descriptor(device, image, is_storage_image,
+                                          view_type, vk_format, mapping,
+                                          first_level, last_level,
+                                          first_layer, last_layer,
+                                          width, height, depth,
+                                          state, fmask_state);
+       }
+}
+
 static void
 radv_query_opaque_metadata(struct radv_device *device,
                           struct radv_image *image,
@@ -807,13 +964,13 @@ radv_query_opaque_metadata(struct radv_device *device,
        md->metadata[1] = si_get_bo_metadata_word1(device);
 
 
-       si_make_texture_descriptor(device, image, false,
-                                  (VkImageViewType)image->type, image->vk_format,
-                                  &fixedmapping, 0, image->info.levels - 1, 0,
-                                  image->info.array_size - 1,
-                                  image->info.width, image->info.height,
-                                  image->info.depth,
-                                  desc, NULL);
+       radv_make_texture_descriptor(device, image, false,
+                                    (VkImageViewType)image->type, image->vk_format,
+                                    &fixedmapping, 0, image->info.levels - 1, 0,
+                                    image->info.array_size - 1,
+                                    image->info.width, image->info.height,
+                                    image->info.depth,
+                                    desc, NULL);
 
        si_set_mutable_tex_desc_fields(device, image, &image->planes[0].surface.u.legacy.level[0], 0, 0, 0,
                                       image->planes[0].surface.blk_w, false, false, desc);
@@ -1250,18 +1407,18 @@ radv_image_view_make_descriptor(struct radv_image_view *iview,
 
        if (device->physical_device->rad_info.chip_class >= GFX9)
                hw_level = iview->base_mip;
-       si_make_texture_descriptor(device, image, is_storage_image,
-                                  iview->type,
-                                  vk_format,
-                                  components,
-                                  hw_level, hw_level + iview->level_count - 1,
-                                  iview->base_layer,
-                                  iview->base_layer + iview->layer_count - 1,
-                                  iview->extent.width  / (plane_id ? format_desc->width_divisor : 1),
-                                  iview->extent.height  / (plane_id ? format_desc->height_divisor : 1),
-                                  iview->extent.depth,
-                                  descriptor->plane_descriptors[descriptor_plane_id],
-                                  descriptor_plane_id ? NULL : descriptor->fmask_descriptor);
+       radv_make_texture_descriptor(device, image, is_storage_image,
+                                    iview->type,
+                                    vk_format,
+                                    components,
+                                    hw_level, hw_level + iview->level_count - 1,
+                                    iview->base_layer,
+                                    iview->base_layer + iview->layer_count - 1,
+                                    iview->extent.width  / (plane_id ? format_desc->width_divisor : 1),
+                                    iview->extent.height  / (plane_id ? format_desc->height_divisor : 1),
+                                    iview->extent.depth,
+                                    descriptor->plane_descriptors[descriptor_plane_id],
+                                    descriptor_plane_id ? NULL : descriptor->fmask_descriptor);
 
        const struct legacy_surf_level *base_level_info = NULL;
        if (device->physical_device->rad_info.chip_class <= GFX9) {