v3dv: emit scissor to render area and precompute hw color clear values
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 03421aa..6959ccc 100644
--- a/src/broadcom/vulkan/v3dv_cmd_buffer.c
+++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c
@@ -23,6 +23,7 @@
#include "v3dv_private.h"
#include "broadcom/cle/v3dx_pack.h"
+#include "util/u_pack_color.h"
void
v3dv_cmd_buffer_add_bo(struct v3dv_cmd_buffer *cmd_buffer, struct v3dv_bo *bo)
@@ -235,6 +236,62 @@
return VK_SUCCESS;
}
+static void
+emit_clip_window(struct v3dv_cmd_buffer *cmd_buffer, VkRect2D *rect)
+{
+ cl_emit(&cmd_buffer->bcl, CLIP_WINDOW, clip) {
+ clip.clip_window_left_pixel_coordinate = rect->offset.x;
+ clip.clip_window_bottom_pixel_coordinate = rect->offset.y;
+ clip.clip_window_width_in_pixels = rect->extent.width;
+ clip.clip_window_height_in_pixels = rect->extent.height;
+ }
+}
+
+static void
+compute_tlb_color_clear(struct v3dv_cmd_buffer *cmd_buffer,
+ uint32_t attachment_idx,
+ const VkClearColorValue *color)
+{
+ assert(attachment_idx < cmd_buffer->state.framebuffer->attachment_count);
+
+ struct v3dv_image_view *iview =
+ cmd_buffer->state.framebuffer->attachments[attachment_idx];
+ uint32_t internal_size = 4 << iview->internal_bpp;
+
+ struct v3dv_cmd_buffer_attachment_state *attachment =
+ &cmd_buffer->state.attachments[attachment_idx];
+ uint32_t *hw_color = &attachment->clear_value.color[0];
+
+ union util_color uc;
+ switch (iview->internal_type) {
+ case V3D_INTERNAL_TYPE_8:
+ util_pack_color(color->float32, PIPE_FORMAT_R8G8B8A8_UNORM, &uc);
+ memcpy(hw_color, uc.ui, internal_size);
+ break;
+ case V3D_INTERNAL_TYPE_8I:
+ case V3D_INTERNAL_TYPE_8UI:
+ hw_color[0] = ((color->uint32[0] & 0xff) |
+ (color->uint32[1] & 0xff) << 8 |
+ (color->uint32[2] & 0xff) << 16 |
+ (color->uint32[3] & 0xff) << 24);
+ break;
+ case V3D_INTERNAL_TYPE_16F:
+ util_pack_color(color->float32, PIPE_FORMAT_R16G16B16A16_FLOAT, &uc);
+ memcpy(hw_color, uc.ui, internal_size);
+ break;
+ case V3D_INTERNAL_TYPE_16I:
+ case V3D_INTERNAL_TYPE_16UI:
+ hw_color[0] = ((color->uint32[0] & 0xffff) | color->uint32[1] << 16);
+ hw_color[1] = ((color->uint32[2] & 0xffff) | color->uint32[3] << 16);
+ break;
+ case V3D_INTERNAL_TYPE_32F:
+ case V3D_INTERNAL_TYPE_32I:
+ case V3D_INTERNAL_TYPE_32UI:
+ memcpy(hw_color, color->uint32, internal_size);
+ break;
+ }
+}
+
void
v3dv_CmdBeginRenderPass(VkCommandBuffer commandBuffer,
const VkRenderPassBeginInfo *pRenderPassBegin,
@@ -310,6 +367,39 @@
* any prefix state data before the binning list proper starts."
*/
cl_emit(&cmd_buffer->bcl, START_TILE_BINNING, bin);
+
+ /* FIXME: might want to merge actual scissor rect here if possible */
+ /* FIXME: probably need to align the render area to tile boundaries since
+ * the tile clears will render full tiles anyway.
+ * See vkGetRenderAreaGranularity().
+ */
+ cmd_buffer->state.render_area = pRenderPassBegin->renderArea;
+ emit_clip_window(cmd_buffer, &cmd_buffer->state.render_area);
+
+ /* Compute tile color clear values */
+ for (uint32_t i = 0; i < cmd_buffer->state.pass->attachment_count; i++) {
+ const struct v3dv_render_pass_attachment *attachment =
+ &cmd_buffer->state.pass->attachments[i];
+
+ if (attachment->desc.loadOp != VK_ATTACHMENT_LOAD_OP_CLEAR)
+ continue;
+
+ const struct v3dv_image_view *iview =
+ cmd_buffer->state.framebuffer->attachments[i];
+
+ /* FIXME: support depth/stencil clear */
+ assert((iview->aspects &
+ (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) == 0);
+
+ if (iview->aspects & VK_IMAGE_ASPECT_COLOR_BIT) {
+ const VkClearColorValue *clear_color =
+ &pRenderPassBegin->pClearValues[i].color;
+ compute_tlb_color_clear(cmd_buffer, i, clear_color);
+ }
+ }
+
+ /* Setup for first subpass */
+ cmd_buffer->state.subpass_idx = 0;
}
void
diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h
index 5bd2e94..4484a34 100644
--- a/src/broadcom/vulkan/v3dv_private.h
+++ b/src/broadcom/vulkan/v3dv_private.h
@@ -358,9 +358,23 @@
V3DV_CMD_BUFFER_STATUS_RECORDING = 2
};
+union v3dv_clear_value {
+ uint32_t color[4];
+ float z;
+ uint8_t s;
+};
+
+struct v3dv_cmd_buffer_attachment_state {
+ union v3dv_clear_value clear_value;
+};
+
struct v3dv_cmd_buffer_state {
const struct v3dv_render_pass *pass;
const struct v3dv_framebuffer *framebuffer;
+ VkRect2D render_area;
+ struct v3dv_cmd_buffer_attachment_state attachments[6]; /* FIXME */
+
+ uint32_t subpass_idx;
};
struct v3dv_cmd_buffer {