radv: Track scratch usage across pipelines & command buffers.
[mesa.git] / src / amd / vulkan / radv_image.c
index c6318f28826dfac47b18da535e9565d18d5ea4df..f75f00884956586c36f09a6618a5a4bd0bdd7d27 100644 (file)
@@ -112,8 +112,8 @@ radv_init_surface(struct radv_device *device,
                                   VK_IMAGE_USAGE_STORAGE_BIT)) ||
            (pCreateInfo->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) ||
             (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) ||
-            device->instance->physicalDevice.rad_info.chip_class < VI ||
-            create_info->scanout || !device->allow_dcc ||
+            device->physical_device->rad_info.chip_class < VI ||
+            create_info->scanout || (device->debug_flags & RADV_DEBUG_NO_DCC) ||
             !radv_is_colorbuffer_format_supported(pCreateInfo->format, &blendable))
                surface->flags |= RADEON_SURF_DISABLE_DCC;
        if (create_info->scanout)
@@ -123,7 +123,7 @@ radv_init_surface(struct radv_device *device,
 #define ATI_VENDOR_ID 0x1002
 static uint32_t si_get_bo_metadata_word1(struct radv_device *device)
 {
-       return (ATI_VENDOR_ID << 16) | device->instance->physicalDevice.rad_info.pci_id;
+       return (ATI_VENDOR_ID << 16) | device->physical_device->rad_info.pci_id;
 }
 
 static inline unsigned
@@ -326,7 +326,7 @@ si_make_texture_descriptor(struct radv_device *device,
                /* The last dword is unused by hw. The shader uses it to clear
                 * bits in the first dword of sampler state.
                 */
-               if (device->instance->physicalDevice.rad_info.chip_class <= CIK && image->samples <= 1) {
+               if (device->physical_device->rad_info.chip_class <= CIK && image->samples <= 1) {
                        if (first_level == last_level)
                                state[7] = C_008F30_MAX_ANISO_RATIO;
                        else
@@ -517,8 +517,8 @@ radv_image_get_cmask_info(struct radv_device *device,
                          struct radv_image *image,
                          struct radv_cmask_info *out)
 {
-       unsigned pipe_interleave_bytes = device->instance->physicalDevice.rad_info.pipe_interleave_bytes;
-       unsigned num_pipes = device->instance->physicalDevice.rad_info.num_tile_pipes;
+       unsigned pipe_interleave_bytes = device->physical_device->rad_info.pipe_interleave_bytes;
+       unsigned num_pipes = device->physical_device->rad_info.num_tile_pipes;
        unsigned cl_width, cl_height;
 
        switch (num_pipes) {
@@ -589,8 +589,8 @@ radv_image_get_htile_size(struct radv_device *device,
 {
        unsigned cl_width, cl_height, width, height;
        unsigned slice_elements, slice_bytes, base_align;
-       unsigned num_pipes = device->instance->physicalDevice.rad_info.num_tile_pipes;
-       unsigned pipe_interleave_bytes = device->instance->physicalDevice.rad_info.pipe_interleave_bytes;
+       unsigned num_pipes = device->physical_device->rad_info.num_tile_pipes;
+       unsigned pipe_interleave_bytes = device->physical_device->rad_info.pipe_interleave_bytes;
 
        /* Overalign HTILE on P2 configs to work around GPU hangs in
         * piglit/depthstencil-render-miplevels 585.
@@ -599,7 +599,7 @@ radv_image_get_htile_size(struct radv_device *device,
         * are always reproducible. I think I have seen the test hang
         * on Carrizo too, though it was very rare there.
         */
-       if (device->instance->physicalDevice.rad_info.chip_class >= CIK && num_pipes < 4)
+       if (device->physical_device->rad_info.chip_class >= CIK && num_pipes < 4)
                num_pipes = 4;
 
        switch (num_pipes) {
@@ -649,7 +649,7 @@ static void
 radv_image_alloc_htile(struct radv_device *device,
                       struct radv_image *image)
 {
-       if (env_var_as_boolean("RADV_HIZ_DISABLE", false))
+       if (device->debug_flags & RADV_DEBUG_NO_HIZ)
                return;
 
        image->htile.size = radv_image_get_htile_size(device, image);
@@ -674,7 +674,7 @@ radv_image_create(VkDevice _device,
        RADV_FROM_HANDLE(radv_device, device, _device);
        const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
        struct radv_image *image = NULL;
-
+       bool can_cmask_dcc = false;
        assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
 
        radv_assert(pCreateInfo->mipLevels > 0);
@@ -698,6 +698,13 @@ radv_image_create(VkDevice _device,
        image->samples = pCreateInfo->samples;
        image->tiling = pCreateInfo->tiling;
        image->usage = pCreateInfo->usage;
+
+       image->exclusive = pCreateInfo->sharingMode == VK_SHARING_MODE_EXCLUSIVE;
+       if (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) {
+               for (uint32_t i = 0; i < pCreateInfo->queueFamilyIndexCount; ++i)
+                       image->queue_family_mask |= 1u << pCreateInfo->pQueueFamilyIndices[i];
+       }
+
        radv_init_surface(device, &image->surface, create_info);
 
        device->ws->surface_init(device->ws, &image->surface);
@@ -705,15 +712,18 @@ radv_image_create(VkDevice _device,
        image->size = image->surface.bo_size;
        image->alignment = image->surface.bo_alignment;
 
+       if (image->exclusive || image->queue_family_mask == 1)
+               can_cmask_dcc = true;
+
        if ((pCreateInfo->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) &&
-           image->surface.dcc_size)
+           image->surface.dcc_size && can_cmask_dcc)
                radv_image_alloc_dcc(device, image);
        else
                image->surface.dcc_size = 0;
 
        if ((pCreateInfo->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) &&
            pCreateInfo->mipLevels == 1 &&
-           !image->surface.dcc_size && image->extent.depth == 1)
+           !image->surface.dcc_size && image->extent.depth == 1 && can_cmask_dcc)
                radv_image_alloc_cmask(device, image);
        if (image->samples > 1 && vk_format_is_color(pCreateInfo->format)) {
                radv_image_alloc_fmask(device, image);
@@ -742,6 +752,7 @@ radv_image_view_init(struct radv_image_view *iview,
 {
        RADV_FROM_HANDLE(radv_image, image, pCreateInfo->image);
        const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
+       uint32_t blk_w;
        bool is_stencil = false;
        switch (image->type) {
        case VK_IMAGE_TYPE_1D:
@@ -779,6 +790,8 @@ radv_image_view_init(struct radv_image_view *iview,
        iview->extent.height = round_up_u32(iview->extent.height * vk_format_get_blockheight(iview->vk_format),
                                            vk_format_get_blockheight(image->vk_format));
 
+       assert(image->surface.blk_w % vk_format_get_blockwidth(image->vk_format) == 0);
+       blk_w = image->surface.blk_w / vk_format_get_blockwidth(image->vk_format) * vk_format_get_blockwidth(iview->vk_format);
        iview->base_layer = range->baseArrayLayer;
        iview->layer_count = radv_get_layerCount(image, range);
        iview->base_mip = range->baseMipLevel;
@@ -798,7 +811,7 @@ radv_image_view_init(struct radv_image_view *iview,
        si_set_mutable_tex_desc_fields(device, image,
                                       is_stencil ? &image->surface.stencil_level[range->baseMipLevel] : &image->surface.level[range->baseMipLevel], range->baseMipLevel,
                                       range->baseMipLevel,
-                                      image->surface.blk_w, is_stencil, iview->descriptor);
+                                      blk_w, is_stencil, iview->descriptor);
 }
 
 void radv_image_set_optimal_micro_tile_mode(struct radv_device *device,
@@ -808,7 +821,7 @@ void radv_image_set_optimal_micro_tile_mode(struct radv_device *device,
         * definitions for them either. They are all 2D_TILED_THIN1 modes with
         * different bpp and micro tile mode.
         */
-       if (device->instance->physicalDevice.rad_info.chip_class >= CIK) {
+       if (device->physical_device->rad_info.chip_class >= CIK) {
                switch (micro_tile_mode) {
                case 0: /* displayable */
                        image->surface.tiling_index[0] = 10;
@@ -883,11 +896,19 @@ bool radv_layout_can_expclear(const struct radv_image *image,
                layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
 }
 
-bool radv_layout_has_cmask(const struct radv_image *image,
-                          VkImageLayout layout)
+bool radv_layout_can_fast_clear(const struct radv_image *image,
+                               VkImageLayout layout,
+                               unsigned queue_mask)
 {
-       return (layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL ||
-               layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
+       return layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL &&
+               queue_mask == (1u << RADV_QUEUE_GENERAL);
+}
+
+
+unsigned radv_image_queue_family_mask(const struct radv_image *image, int family) {
+       if (image->exclusive)
+               return 1u <<family;
+       return image->queue_family_mask;
 }
 
 VkResult