v3dv: consider MSAA when computing frame tiling
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6766>
diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c
index 1f3d171..5cd5a70 100644
--- a/src/broadcom/vulkan/v3dv_cmd_buffer.c
+++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c
@@ -445,7 +445,8 @@
uint32_t height,
uint32_t layers,
uint32_t render_target_count,
- uint8_t max_internal_bpp)
+ uint8_t max_internal_bpp,
+ bool msaa)
{
static const uint8_t tile_sizes[] = {
64, 64,
@@ -462,16 +463,18 @@
tiling->height = height;
tiling->layers = layers;
tiling->render_target_count = render_target_count;
+ tiling->msaa = msaa;
uint32_t tile_size_index = 0;
- /* FIXME: MSAA */
-
if (render_target_count > 2)
tile_size_index += 2;
else if (render_target_count > 1)
tile_size_index += 1;
+ if (msaa)
+ tile_size_index += 2;
+
tiling->internal_bpp = max_internal_bpp;
tile_size_index += tiling->internal_bpp;
assert(tile_size_index < ARRAY_SIZE(tile_sizes));
@@ -511,7 +514,8 @@
uint32_t height,
uint32_t layers,
uint32_t render_target_count,
- uint8_t max_internal_bpp)
+ uint8_t max_internal_bpp,
+ bool msaa)
{
assert(job);
@@ -519,7 +523,7 @@
const struct v3dv_frame_tiling *tiling =
job_compute_frame_tiling(job,
width, height, layers,
- render_target_count, max_internal_bpp);
+ render_target_count, max_internal_bpp, msaa);
v3dv_cl_ensure_space_with_branch(&job->bcl, 256);
v3dv_return_if_oom(NULL, job);
@@ -2115,15 +2119,18 @@
const struct v3dv_framebuffer *framebuffer = state->framebuffer;
- const uint8_t internal_bpp =
- v3dv_framebuffer_compute_internal_bpp(framebuffer, subpass);
+ uint8_t internal_bpp;
+ bool msaa;
+ v3dv_framebuffer_compute_internal_bpp_msaa(framebuffer, subpass,
+ &internal_bpp, &msaa);
v3dv_job_start_frame(job,
framebuffer->width,
framebuffer->height,
framebuffer->layers,
subpass->color_count,
- internal_bpp);
+ internal_bpp,
+ msaa);
/* FIXME: we don't suppport resolve attachments yet */
assert(subpass->resolve_attachments == NULL);
diff --git a/src/broadcom/vulkan/v3dv_device.c b/src/broadcom/vulkan/v3dv_device.c
index 7e819c5..0494303 100644
--- a/src/broadcom/vulkan/v3dv_device.c
+++ b/src/broadcom/vulkan/v3dv_device.c
@@ -1917,15 +1917,20 @@
/**
* This computes the maximum bpp used by any of the render targets used by
- * a particular subpass. If we don't have a subpass (when we are not inside a
+ * a particular subpass and checks if any of those render targets are
+ * multisampled. If we don't have a subpass (when we are not inside a
* render pass), then we assume that all framebuffer attachments are used.
*/
-uint8_t
-v3dv_framebuffer_compute_internal_bpp(const struct v3dv_framebuffer *framebuffer,
- const struct v3dv_subpass *subpass)
+void
+v3dv_framebuffer_compute_internal_bpp_msaa(
+ const struct v3dv_framebuffer *framebuffer,
+ const struct v3dv_subpass *subpass,
+ uint8_t *max_bpp,
+ bool *msaa)
{
STATIC_ASSERT(RENDER_TARGET_MAXIMUM_32BPP == 0);
- uint8_t max_bpp = RENDER_TARGET_MAXIMUM_32BPP;
+ *max_bpp = RENDER_TARGET_MAXIMUM_32BPP;
+ *msaa = false;
if (subpass) {
for (uint32_t i = 0; i < subpass->color_count; i++) {
@@ -1937,10 +1942,22 @@
assert(att);
if (att->aspects & VK_IMAGE_ASPECT_COLOR_BIT)
- max_bpp = MAX2(max_bpp, att->internal_bpp);
+ *max_bpp = MAX2(*max_bpp, att->internal_bpp);
+
+ if (att->image->samples > VK_SAMPLE_COUNT_1_BIT)
+ *msaa = true;
}
- return max_bpp;
+ if (!*msaa && subpass->ds_attachment.attachment != VK_ATTACHMENT_UNUSED) {
+ const struct v3dv_image_view *att =
+ framebuffer->attachments[subpass->ds_attachment.attachment];
+ assert(att);
+
+ if (att->image->samples > VK_SAMPLE_COUNT_1_BIT)
+ *msaa = true;
+ }
+
+ return;
}
assert(framebuffer->attachment_count <= 4);
@@ -1949,10 +1966,13 @@
assert(att);
if (att->aspects & VK_IMAGE_ASPECT_COLOR_BIT)
- max_bpp = MAX2(max_bpp, att->internal_bpp);
+ *max_bpp = MAX2(*max_bpp, att->internal_bpp);
+
+ if (att->image->samples > VK_SAMPLE_COUNT_1_BIT)
+ *msaa = true;
}
- return max_bpp;
+ return;
}
VkResult
diff --git a/src/broadcom/vulkan/v3dv_image.c b/src/broadcom/vulkan/v3dv_image.c
index 6bf6405..fb2da0d 100644
--- a/src/broadcom/vulkan/v3dv_image.c
+++ b/src/broadcom/vulkan/v3dv_image.c
@@ -114,7 +114,9 @@
uint32_t block_width = vk_format_get_blockwidth(image->vk_format);
uint32_t block_height = vk_format_get_blockheight(image->vk_format);
- bool msaa = image->samples > VK_SAMPLE_COUNT_1_BIT;
+ assert(image->samples == VK_SAMPLE_COUNT_1_BIT ||
+ image->samples == VK_SAMPLE_COUNT_4_BIT);
+ bool msaa = image->samples != VK_SAMPLE_COUNT_1_BIT;
bool uif_top = msaa;
@@ -328,6 +330,9 @@
if (!image)
return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
+ assert(pCreateInfo->samples == VK_SAMPLE_COUNT_1_BIT ||
+ pCreateInfo->samples == VK_SAMPLE_COUNT_4_BIT);
+
image->type = pCreateInfo->imageType;
image->extent = pCreateInfo->extent;
image->vk_format = pCreateInfo->format;
diff --git a/src/broadcom/vulkan/v3dv_meta_clear.c b/src/broadcom/vulkan/v3dv_meta_clear.c
index 9a7020f..07d2a20 100644
--- a/src/broadcom/vulkan/v3dv_meta_clear.c
+++ b/src/broadcom/vulkan/v3dv_meta_clear.c
@@ -1300,15 +1300,17 @@
}
}
- const uint8_t internal_bpp =
- v3dv_framebuffer_compute_internal_bpp(framebuffer, subpass);
+ uint8_t internal_bpp;
+ bool msaa;
+ v3dv_framebuffer_compute_internal_bpp_msaa(framebuffer, subpass,
+ &internal_bpp, &msaa);
v3dv_job_start_frame(job,
framebuffer->width,
framebuffer->height,
framebuffer->layers,
color_attachment_count,
- internal_bpp);
+ internal_bpp, msaa);
struct v3dv_cl *rcl = &job->rcl;
v3dv_cl_ensure_space_with_branch(rcl, 200 +
diff --git a/src/broadcom/vulkan/v3dv_meta_copy.c b/src/broadcom/vulkan/v3dv_meta_copy.c
index 3f1f15b..c930669 100644
--- a/src/broadcom/vulkan/v3dv_meta_copy.c
+++ b/src/broadcom/vulkan/v3dv_meta_copy.c
@@ -691,7 +691,7 @@
const uint32_t width = DIV_ROUND_UP(region->imageExtent.width, block_w);
const uint32_t height = DIV_ROUND_UP(region->imageExtent.height, block_h);
- v3dv_job_start_frame(job, width, height, num_layers, 1, internal_bpp);
+ v3dv_job_start_frame(job, width, height, num_layers, 1, internal_bpp, false);
struct framebuffer_data framebuffer;
setup_framebuffer_data(&framebuffer, fb_format, internal_type,
@@ -1185,7 +1185,7 @@
const uint32_t width = DIV_ROUND_UP(region->extent.width, block_w);
const uint32_t height = DIV_ROUND_UP(region->extent.height, block_h);
- v3dv_job_start_frame(job, width, height, num_layers, 1, internal_bpp);
+ v3dv_job_start_frame(job, width, height, num_layers, 1, internal_bpp, false);
struct framebuffer_data framebuffer;
setup_framebuffer_data(&framebuffer, fb_format, internal_type,
@@ -1501,7 +1501,7 @@
return true;
/* We start a a new job for each layer so the frame "depth" is 1 */
- v3dv_job_start_frame(job, width, height, 1, 1, internal_bpp);
+ v3dv_job_start_frame(job, width, height, 1, 1, internal_bpp, false);
struct framebuffer_data framebuffer;
setup_framebuffer_data(&framebuffer, fb_format, internal_type,
@@ -1728,7 +1728,7 @@
uint32_t width, height;
framebuffer_size_for_pixel_count(num_items, &width, &height);
- v3dv_job_start_frame(job, width, height, 1, 1, internal_bpp);
+ v3dv_job_start_frame(job, width, height, 1, 1, internal_bpp, false);
struct framebuffer_data framebuffer;
setup_framebuffer_data(&framebuffer, vk_format, internal_type,
@@ -1917,7 +1917,7 @@
uint32_t width, height;
framebuffer_size_for_pixel_count(num_items, &width, &height);
- v3dv_job_start_frame(job, width, height, 1, 1, internal_bpp);
+ v3dv_job_start_frame(job, width, height, 1, 1, internal_bpp, false);
struct framebuffer_data framebuffer;
setup_framebuffer_data(&framebuffer, VK_FORMAT_R8G8B8A8_UINT,
@@ -2270,7 +2270,7 @@
const uint32_t width = DIV_ROUND_UP(region->imageExtent.width, block_w);
const uint32_t height = DIV_ROUND_UP(region->imageExtent.height, block_h);
- v3dv_job_start_frame(job, width, height, num_layers, 1, internal_bpp);
+ v3dv_job_start_frame(job, width, height, num_layers, 1, internal_bpp, false);
struct framebuffer_data framebuffer;
setup_framebuffer_data(&framebuffer, fb_format, internal_type,
diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h
index 4b4f3da..e0d7440 100644
--- a/src/broadcom/vulkan/v3dv_private.h
+++ b/src/broadcom/vulkan/v3dv_private.h
@@ -559,9 +559,10 @@
struct v3dv_frame_tiling {
uint32_t width;
uint32_t height;
+ uint32_t layers;
uint32_t render_target_count;
uint32_t internal_bpp;
- uint32_t layers;
+ bool msaa;
uint32_t tile_width;
uint32_t tile_height;
uint32_t draw_tiles_x;
@@ -572,8 +573,9 @@
uint32_t frame_height_in_supertiles;
};
-uint8_t v3dv_framebuffer_compute_internal_bpp(const struct v3dv_framebuffer *framebuffer,
- const struct v3dv_subpass *subpass);
+void v3dv_framebuffer_compute_internal_bpp_msaa(const struct v3dv_framebuffer *framebuffer,
+ const struct v3dv_subpass *subpass,
+ uint8_t *max_bpp, bool *msaa);
struct v3dv_cmd_pool {
VkAllocationCallbacks alloc;
@@ -880,7 +882,8 @@
uint32_t height,
uint32_t layers,
uint32_t render_target_count,
- uint8_t max_internal_bpp);
+ uint8_t max_internal_bpp,
+ bool msaa);
struct v3dv_job *v3dv_cmd_buffer_create_cpu_job(struct v3dv_device *device,
enum v3dv_job_type type,
struct v3dv_cmd_buffer *cmd_buffer,
diff --git a/src/broadcom/vulkan/v3dv_queue.c b/src/broadcom/vulkan/v3dv_queue.c
index a5a7164..895493f 100644
--- a/src/broadcom/vulkan/v3dv_queue.c
+++ b/src/broadcom/vulkan/v3dv_queue.c
@@ -713,7 +713,7 @@
static void
emit_noop_bin(struct v3dv_job *job)
{
- v3dv_job_start_frame(job, 1, 1, 1, 1, V3D_INTERNAL_BPP_32);
+ v3dv_job_start_frame(job, 1, 1, 1, 1, V3D_INTERNAL_BPP_32, false);
v3dv_job_emit_binning_flush(job);
}