aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/amd/vulkan/radv_meta_clear.c56
1 files changed, 46 insertions, 10 deletions
diff --git a/src/amd/vulkan/radv_meta_clear.c b/src/amd/vulkan/radv_meta_clear.c
index 8805f0435e1..140e14c95e0 100644
--- a/src/amd/vulkan/radv_meta_clear.c
+++ b/src/amd/vulkan/radv_meta_clear.c
@@ -370,14 +370,29 @@ emit_color_clear(struct radv_cmd_buffer *cmd_buffer,
const struct radv_framebuffer *fb = cmd_buffer->state.framebuffer;
const uint32_t subpass_att = clear_att->colorAttachment;
const uint32_t pass_att = subpass->color_attachments[subpass_att].attachment;
- const struct radv_image_view *iview = fb->attachments[pass_att].attachment;
- const uint32_t samples = iview->image->info.samples;
- const uint32_t samples_log2 = ffs(samples) - 1;
- unsigned fs_key = radv_format_meta_fs_key(iview->vk_format);
+ const struct radv_image_view *iview = fb ? fb->attachments[pass_att].attachment : NULL;
+ uint32_t samples, samples_log2;
+ VkFormat format;
+ unsigned fs_key;
VkClearColorValue clear_value = clear_att->clearValue.color;
VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer);
VkPipeline pipeline;
+ /* When a framebuffer is bound to the current command buffer, get the
+ * number of samples from it. Otherwise, get the number of samples from
+ * the render pass because it's likely a secondary command buffer.
+ */
+ if (iview) {
+ samples = iview->image->info.samples;
+ format = iview->vk_format;
+ } else {
+ samples = cmd_buffer->state.pass->attachments[pass_att].samples;
+ format = cmd_buffer->state.pass->attachments[pass_att].format;
+ }
+
+ samples_log2 = ffs(samples) - 1;
+ fs_key = radv_format_meta_fs_key(format);
+
if (fs_key == -1) {
radv_finishme("color clears incomplete");
return;
@@ -617,6 +632,9 @@ static bool depth_view_can_fast_clear(struct radv_cmd_buffer *cmd_buffer,
const VkClearRect *clear_rect,
VkClearDepthStencilValue clear_value)
{
+ if (!iview)
+ return false;
+
uint32_t queue_mask = radv_image_queue_family_mask(iview->image,
cmd_buffer->queue_family_index,
cmd_buffer->queue_family_index);
@@ -705,11 +723,22 @@ emit_depthstencil_clear(struct radv_cmd_buffer *cmd_buffer,
const uint32_t pass_att = subpass->depth_stencil_attachment.attachment;
VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil;
VkImageAspectFlags aspects = clear_att->aspectMask;
- const struct radv_image_view *iview = fb->attachments[pass_att].attachment;
- const uint32_t samples = iview->image->info.samples;
- const uint32_t samples_log2 = ffs(samples) - 1;
+ const struct radv_image_view *iview = fb ? fb->attachments[pass_att].attachment : NULL;
+ uint32_t samples, samples_log2;
VkCommandBuffer cmd_buffer_h = radv_cmd_buffer_to_handle(cmd_buffer);
+ /* When a framebuffer is bound to the current command buffer, get the
+ * number of samples from it. Otherwise, get the number of samples from
+ * the render pass because it's likely a secondary command buffer.
+ */
+ if (iview) {
+ samples = iview->image->info.samples;
+ } else {
+ samples = cmd_buffer->state.pass->attachments[pass_att].samples;
+ }
+
+ samples_log2 = ffs(samples) - 1;
+
assert(pass_att != VK_ATTACHMENT_UNUSED);
if (!(aspects & VK_IMAGE_ASPECT_DEPTH_BIT))
@@ -915,7 +944,11 @@ static bool
radv_image_view_can_fast_clear(struct radv_device *device,
const struct radv_image_view *iview)
{
- struct radv_image *image = iview->image;
+ struct radv_image *image;
+
+ if (!iview)
+ return false;
+ image = iview->image;
/* Only fast clear if the image itself can be fast cleared. */
if (!radv_image_can_fast_clear(device, image))
@@ -1523,7 +1556,7 @@ emit_clear(struct radv_cmd_buffer *cmd_buffer,
const uint32_t subpass_att = clear_att->colorAttachment;
const uint32_t pass_att = subpass->color_attachments[subpass_att].attachment;
VkImageLayout image_layout = subpass->color_attachments[subpass_att].layout;
- const struct radv_image_view *iview = fb->attachments[pass_att].attachment;
+ const struct radv_image_view *iview = fb ? fb->attachments[pass_att].attachment : NULL;
VkClearColorValue clear_value = clear_att->clearValue.color;
if (radv_can_fast_clear_color(cmd_buffer, iview, image_layout,
@@ -1536,8 +1569,11 @@ emit_clear(struct radv_cmd_buffer *cmd_buffer,
}
} else {
const uint32_t pass_att = subpass->depth_stencil_attachment.attachment;
+ if (pass_att == VK_ATTACHMENT_UNUSED)
+ return;
+
VkImageLayout image_layout = subpass->depth_stencil_attachment.layout;
- const struct radv_image_view *iview = fb->attachments[pass_att].attachment;
+ const struct radv_image_view *iview = fb ? fb->attachments[pass_att].attachment : NULL;
VkClearDepthStencilValue clear_value = clear_att->clearValue.depthStencil;
assert(aspects & (VK_IMAGE_ASPECT_DEPTH_BIT |