pvr: Add layer count support to pvr_clear_vdm_state().
authorKarmjit Mahil <Karmjit.Mahil@imgtec.com>
Wed, 21 Sep 2022 15:41:10 +0000 (16:41 +0100)
committerMarge Bot <emma+marge@anholt.net>
Wed, 4 Jan 2023 16:30:39 +0000 (16:30 +0000)
Signed-off-by: Karmjit Mahil <Karmjit.Mahil@imgtec.com>
Reviewed-by: Frank Binns <frank.binns@imgtec.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20055>

src/imagination/vulkan/pvr_clear.c
src/imagination/vulkan/pvr_clear.h
src/imagination/vulkan/pvr_device.c

index f9ac65c..96e8e75 100644 (file)
@@ -259,15 +259,23 @@ void pvr_pack_clear_vdm_state(
    uint32_t temps,
    uint32_t index_count,
    uint32_t vs_output_size_in_bytes,
+   uint32_t layer_count,
    uint32_t state_buffer[const static PVR_CLEAR_VDM_STATE_DWORD_COUNT])
 {
    const uint32_t vs_output_size =
       DIV_ROUND_UP(vs_output_size_in_bytes,
                    PVRX(VDMCTRL_VDM_STATE4_VS_OUTPUT_SIZE_UNIT_SIZE));
+   const bool needs_instance_count =
+      !PVR_HAS_FEATURE(dev_info, gs_rta_support) && layer_count > 1;
    uint32_t *stream = state_buffer;
    uint32_t max_instances;
    uint32_t cam_size;
 
+   /* The layer count should at least be 1. For vkCmdClearAttachment() the spec.
+    * guarantees that the layer count is not 0.
+    */
+   assert(layer_count != 0);
+
    pvr_calculate_vertex_cam_size(dev_info,
                                  vs_output_size,
                                  true,
@@ -301,9 +309,11 @@ void pvr_pack_clear_vdm_state(
 
    pvr_csb_pack (stream, VDMCTRL_VDM_STATE5, state5) {
       state5.vs_max_instances = max_instances;
-      /* TODO: Where does the 3 * sizeof(uint32_t) come from? */
+      /* This is the size of the input vertex. The hw manages the USC
+       * temporaries separately so we don't need to include them here.
+       */
       state5.vs_usc_unified_size =
-         DIV_ROUND_UP(3 * sizeof(uint32_t),
+         DIV_ROUND_UP(PVR_CLEAR_VERTEX_COORDINATES * sizeof(uint32_t),
                       PVRX(VDMCTRL_VDM_STATE5_VS_USC_UNIFIED_SIZE_UNIT_SIZE));
       state5.vs_pds_temp_size =
          DIV_ROUND_UP(temps,
@@ -316,6 +326,7 @@ void pvr_pack_clear_vdm_state(
 
    pvr_csb_pack (stream, VDMCTRL_INDEX_LIST0, index_list0) {
       index_list0.index_count_present = true;
+      index_list0.index_instance_count_present = needs_instance_count;
       index_list0.primitive_topology =
          PVRX(VDMCTRL_PRIMITIVE_TOPOLOGY_TRI_STRIP);
    }
@@ -326,5 +337,12 @@ void pvr_pack_clear_vdm_state(
    }
    stream += pvr_cmd_length(VDMCTRL_INDEX_LIST2);
 
-   assert((uint64_t)(stream - state_buffer) == PVR_CLEAR_VDM_STATE_DWORD_COUNT);
+   if (needs_instance_count) {
+      pvr_csb_pack (stream, VDMCTRL_INDEX_LIST3, index_list3) {
+         index_list3.instance_count = layer_count - 1;
+      }
+      stream += pvr_cmd_length(VDMCTRL_INDEX_LIST3);
+   }
+
+   assert((uint64_t)(stream - state_buffer) <= PVR_CLEAR_VDM_STATE_DWORD_COUNT);
 }
index 7b9fd6f..f8d2b53 100644 (file)
 #define PVR_CLEAR_VERTEX_COUNT 4
 #define PVR_CLEAR_VERTEX_COORDINATES 3
 
+/* We don't always need ROGUE_VDMCTRL_INDEX_LIST3 so maybe change the code to
+ * not have it in here but use an alternative definition when needed if we want
+ * to really squeeze out a some bytes of memory.
+ */
 #define PVR_CLEAR_VDM_STATE_DWORD_COUNT                                        \
    (pvr_cmd_length(VDMCTRL_VDM_STATE0) + pvr_cmd_length(VDMCTRL_VDM_STATE2) +  \
     pvr_cmd_length(VDMCTRL_VDM_STATE3) + pvr_cmd_length(VDMCTRL_VDM_STATE4) +  \
     pvr_cmd_length(VDMCTRL_VDM_STATE5) + pvr_cmd_length(VDMCTRL_INDEX_LIST0) + \
-    pvr_cmd_length(VDMCTRL_INDEX_LIST2))
+    pvr_cmd_length(VDMCTRL_INDEX_LIST2) + pvr_cmd_length(VDMCTRL_INDEX_LIST3))
 
 struct pvr_bo;
 struct pvr_cmd_buffer;
@@ -93,6 +97,7 @@ void pvr_pack_clear_vdm_state(
    uint32_t temps,
    uint32_t index_count,
    uint32_t vs_output_size_in_bytes,
+   uint32_t layer_count,
    uint32_t state_buffer[const static PVR_CLEAR_VDM_STATE_DWORD_COUNT]);
 
 #endif /* PVR_CLEAR_H */
index d6407de..1b1b681 100644 (file)
@@ -1776,6 +1776,7 @@ pvr_device_init_graphics_static_clear_state(struct pvr_device *device)
                             pds_program.temps_used,
                             3,
                             4 * sizeof(uint32_t),
+                            1,
                             state->vdm_words);
 
    /* TODO: Figure out where the 4 * sizeof(uint32_t) comes from. */
@@ -1784,6 +1785,7 @@ pvr_device_init_graphics_static_clear_state(struct pvr_device *device)
                             pds_program.temps_used,
                             4,
                             4 * sizeof(uint32_t),
+                            1,
                             state->large_clear_vdm_words);
 
    return VK_SUCCESS;