radv: create an image for VRS if no depth/stencil attachment is bound

The Vulkan spec doesn't require the application to always binds
a depth/stencil attachment when a VRS attachment is used inside the
same subpass.

To handle this situation, the driver creates a global 4096x4096
VRS image that will be bind at draw-time if needed. This isn't
super ideal but we have to do that unfortunately.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10187>
This commit is contained in:
Samuel Pitoiset 2021-04-07 17:55:00 +02:00 committed by Marge Bot
parent ba7c510e1f
commit bb88f73ad3
2 changed files with 79 additions and 0 deletions

View file

@ -2652,6 +2652,77 @@ radv_device_finish_border_color(struct radv_device *device)
}
}
VkResult
radv_device_init_vrs_image(struct radv_device *device)
{
/* FIXME: 4k depth buffers should be large enough for now but we might want to adjust this
* dynamically at some point. Also, it's probably better to use S8_UINT but no HTILE support yet.
*/
uint32_t width = 4096, height = 4096;
VkMemoryRequirements mem_req;
VkDeviceMemory mem;
VkResult result;
VkImage image;
VkImageCreateInfo image_create_info = {
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
.imageType = VK_IMAGE_TYPE_2D,
.format = VK_FORMAT_D16_UNORM,
.extent = {width, height, 1},
.mipLevels = 1,
.arrayLayers = 1,
.samples = VK_SAMPLE_COUNT_1_BIT,
.tiling = VK_IMAGE_TILING_OPTIMAL,
.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 0,
.pQueueFamilyIndices = NULL,
.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
};
result = radv_CreateImage(radv_device_to_handle(device), &image_create_info,
&device->meta_state.alloc, &image);
if (result != VK_SUCCESS)
return result;
radv_GetImageMemoryRequirements(radv_device_to_handle(device), image, &mem_req);
VkMemoryAllocateInfo alloc_info = {
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
.allocationSize = mem_req.size,
};
result = radv_AllocateMemory(radv_device_to_handle(device), &alloc_info,
&device->meta_state.alloc, &mem);
if (result != VK_SUCCESS)
goto fail_alloc;
result = radv_BindImageMemory(radv_device_to_handle(device), image, mem, 0);
if (result != VK_SUCCESS)
goto fail_bind;
device->vrs.image = radv_image_from_handle(image);
device->vrs.mem = radv_device_memory_from_handle(mem);
return VK_SUCCESS;
fail_bind:
radv_FreeMemory(radv_device_to_handle(device), mem, &device->meta_state.alloc);
fail_alloc:
radv_DestroyImage(radv_device_to_handle(device), image, &device->meta_state.alloc);
return result;
}
static void
radv_device_finish_vrs_image(struct radv_device *device)
{
radv_FreeMemory(radv_device_to_handle(device), radv_device_memory_to_handle(device->vrs.mem),
&device->meta_state.alloc);
radv_DestroyImage(radv_device_to_handle(device), radv_image_to_handle(device->vrs.image),
&device->meta_state.alloc);
}
VkResult
_radv_device_set_lost(struct radv_device *device, const char *file, int line, const char *msg, ...)
{
@ -3070,6 +3141,7 @@ radv_DestroyDevice(VkDevice _device, const VkAllocationCallbacks *pAllocator)
device->ws->buffer_destroy(device->ws, device->gfx_init);
radv_device_finish_border_color(device);
radv_device_finish_vrs_image(device);
for (unsigned i = 0; i < RADV_MAX_QUEUE_FAMILIES; i++) {
for (unsigned q = 0; q < device->queue_count[i]; q++)

View file

@ -835,6 +835,12 @@ struct radv_device {
/* Whether the user forced VRS rates on GFX10.3+. */
enum radv_force_vrs force_vrs;
/* Depth image for VRS when not bound by the app. */
struct {
struct radv_image *image;
struct radv_device_memory *mem;
} vrs;
};
VkResult _radv_device_set_lost(struct radv_device *device, const char *file, int line,
@ -1511,6 +1517,7 @@ void radv_depth_stencil_resolve_subpass_fs(struct radv_cmd_buffer *cmd_buffer,
void radv_emit_default_sample_locations(struct radeon_cmdbuf *cs, int nr_samples);
unsigned radv_get_default_max_sample_dist(int log_samples);
void radv_device_init_msaa(struct radv_device *device);
VkResult radv_device_init_vrs_image(struct radv_device *device);
void radv_update_ds_clear_metadata(struct radv_cmd_buffer *cmd_buffer,
const struct radv_image_view *iview,