pvr: Add clear rta vert shader pds program.
authorKarmjit Mahil <Karmjit.Mahil@imgtec.com>
Wed, 21 Sep 2022 13:40:23 +0000 (14:40 +0100)
committerMarge Bot <emma+marge@anholt.net>
Wed, 4 Jan 2023 16:30:39 +0000 (16:30 +0000)
The rta program will be used in following commits adding support
for vkCmdClearAttachments().

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_cmd_buffer.c
src/imagination/vulkan/pvr_private.h

index 8b93597..e67fd83 100644 (file)
@@ -119,3 +119,136 @@ err_exit:
    *upload_out = (struct pvr_pds_upload){ 0 };
    return result;
 }
+
+VkResult pvr_pds_clear_vertex_shader_program_create_and_upload_data(
+   struct pvr_pds_vertex_shader_program *program,
+   struct pvr_cmd_buffer *cmd_buffer,
+   struct pvr_bo *vertices_bo,
+   struct pvr_pds_upload *const pds_upload_out)
+{
+   struct pvr_device_info *dev_info = &cmd_buffer->device->pdevice->dev_info;
+   uint32_t staging_buffer_size;
+   uint32_t *staging_buffer;
+   VkResult result;
+
+   program->streams[0].address = vertices_bo->vma->dev_addr.addr;
+
+   pvr_pds_vertex_shader(program, NULL, PDS_GENERATE_SIZES, dev_info);
+
+   staging_buffer_size = program->data_size * sizeof(*staging_buffer);
+
+   staging_buffer = vk_alloc(&cmd_buffer->device->vk.alloc,
+                             staging_buffer_size,
+                             8,
+                             VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+   if (!staging_buffer) {
+      *pds_upload_out = (struct pvr_pds_upload){ 0 };
+
+      result = vk_error(cmd_buffer, VK_ERROR_OUT_OF_HOST_MEMORY);
+      cmd_buffer->state.status = result;
+      return result;
+   }
+
+   pvr_pds_vertex_shader(program,
+                         staging_buffer,
+                         PDS_GENERATE_DATA_SEGMENT,
+                         dev_info);
+
+   result = pvr_cmd_buffer_upload_pds(cmd_buffer,
+                                      staging_buffer,
+                                      program->data_size,
+                                      4,
+                                      NULL,
+                                      0,
+                                      0,
+                                      4,
+                                      pds_upload_out);
+   if (result != VK_SUCCESS) {
+      vk_free(&cmd_buffer->device->vk.alloc, staging_buffer);
+
+      *pds_upload_out = (struct pvr_pds_upload){ 0 };
+
+      cmd_buffer->state.status = result;
+      return result;
+   }
+
+   vk_free(&cmd_buffer->device->vk.alloc, staging_buffer);
+
+   return VK_SUCCESS;
+}
+
+void pvr_pds_clear_rta_vertex_shader_program_init_base(
+   struct pvr_pds_vertex_shader_program *program,
+   const struct pvr_bo *usc_shader_bo)
+{
+   pvr_pds_clear_vertex_shader_program_init_base(program, usc_shader_bo);
+
+   /* We'll set the render target index to be the instance id + base array
+    * layer. Since the base array layer can change in between clear rects, we
+    * don't set it here and ask for it when generating the code and data
+    * section.
+    */
+   /* This is 3 because the instance id register will follow the xyz coordinate
+    * registers in the register file.
+    * TODO: Maybe we want this to be hooked up to the compiler?
+    */
+   program->iterate_instance_id = true;
+   program->instance_id_register = 3;
+}
+
+VkResult pvr_pds_clear_rta_vertex_shader_program_create_and_upload_code(
+   struct pvr_pds_vertex_shader_program *program,
+   struct pvr_cmd_buffer *cmd_buffer,
+   uint32_t base_array_layer,
+   struct pvr_pds_upload *const pds_upload_out)
+{
+   struct pvr_device_info *dev_info = &cmd_buffer->device->pdevice->dev_info;
+   uint32_t staging_buffer_size;
+   uint32_t *staging_buffer;
+   VkResult result;
+
+   program->instance_id_modifier = base_array_layer;
+
+   pvr_pds_vertex_shader(program, NULL, PDS_GENERATE_SIZES, dev_info);
+
+   staging_buffer_size = program->code_size * sizeof(*staging_buffer);
+
+   staging_buffer = vk_alloc(&cmd_buffer->device->vk.alloc,
+                             staging_buffer_size,
+                             8,
+                             VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
+   if (!staging_buffer) {
+      *pds_upload_out = (struct pvr_pds_upload){ 0 };
+
+      result = vk_error(cmd_buffer, VK_ERROR_OUT_OF_HOST_MEMORY);
+      cmd_buffer->state.status = result;
+      return result;
+   }
+
+   pvr_pds_vertex_shader(program,
+                         staging_buffer,
+                         PDS_GENERATE_CODE_SEGMENT,
+                         dev_info);
+
+   result = pvr_cmd_buffer_upload_pds(cmd_buffer,
+                                      NULL,
+                                      0,
+                                      0,
+                                      staging_buffer,
+                                      program->code_size,
+                                      4,
+                                      4,
+                                      pds_upload_out);
+   if (result != VK_SUCCESS) {
+      vk_free(&cmd_buffer->device->vk.alloc, staging_buffer);
+
+      *pds_upload_out = (struct pvr_pds_upload){ 0 };
+
+      cmd_buffer->state.status = result;
+      return result;
+   }
+
+   vk_free(&cmd_buffer->device->vk.alloc, staging_buffer);
+
+   return VK_SUCCESS;
+}
index d040c90..4ccc26a 100644 (file)
 #ifndef PVR_CLEAR_H
 #define PVR_CLEAR_H
 
+#include <stdint.h>
 #include <vulkan/vulkan_core.h>
 
 #define PVR_CLEAR_VERTEX_COUNT 4
 #define PVR_CLEAR_VERTEX_COORDINATES 3
 
 struct pvr_bo;
+struct pvr_cmd_buffer;
 struct pvr_device;
 struct pvr_pds_upload;
 struct pvr_pds_vertex_shader_program;
@@ -43,5 +45,37 @@ VkResult pvr_pds_clear_vertex_shader_program_create_and_upload(
    struct pvr_device *device,
    const struct pvr_bo *vertices_bo,
    struct pvr_pds_upload *const upload_out);
+VkResult pvr_pds_clear_vertex_shader_program_create_and_upload_data(
+   struct pvr_pds_vertex_shader_program *program,
+   struct pvr_cmd_buffer *cmd_buffer,
+   struct pvr_bo *vertices_bo,
+   struct pvr_pds_upload *const pds_upload_out);
+
+void pvr_pds_clear_rta_vertex_shader_program_init_base(
+   struct pvr_pds_vertex_shader_program *program,
+   const struct pvr_bo *usc_shader_bo);
+
+/* Each code and data upload function clears the other's fields in the
+ * pds_upload_out. So when uploading the code, the data fields will be 0.
+ */
+VkResult pvr_pds_clear_rta_vertex_shader_program_create_and_upload_code(
+   struct pvr_pds_vertex_shader_program *program,
+   struct pvr_cmd_buffer *cmd_buffer,
+   uint32_t base_array_layer,
+   struct pvr_pds_upload *const pds_upload_out);
+
+static inline VkResult
+pvr_pds_clear_rta_vertex_shader_program_create_and_upload_data(
+   struct pvr_pds_vertex_shader_program *program,
+   struct pvr_cmd_buffer *cmd_buffer,
+   struct pvr_bo *vertices_bo,
+   struct pvr_pds_upload *const pds_upload_out)
+{
+   return pvr_pds_clear_vertex_shader_program_create_and_upload_data(
+      program,
+      cmd_buffer,
+      vertices_bo,
+      pds_upload_out);
+}
 
 #endif /* PVR_CLEAR_H */
index 175145b..c9ef4d1 100644 (file)
@@ -419,16 +419,15 @@ pvr_cmd_buffer_upload_usc(struct pvr_cmd_buffer *const cmd_buffer,
    return VK_SUCCESS;
 }
 
-static VkResult
-pvr_cmd_buffer_upload_pds(struct pvr_cmd_buffer *const cmd_buffer,
-                          const uint32_t *data,
-                          uint32_t data_size_dwords,
-                          uint32_t data_alignment,
-                          const uint32_t *code,
-                          uint32_t code_size_dwords,
-                          uint32_t code_alignment,
-                          uint64_t min_alignment,
-                          struct pvr_pds_upload *const pds_upload_out)
+VkResult pvr_cmd_buffer_upload_pds(struct pvr_cmd_buffer *const cmd_buffer,
+                                   const uint32_t *data,
+                                   uint32_t data_size_dwords,
+                                   uint32_t data_alignment,
+                                   const uint32_t *code,
+                                   uint32_t code_size_dwords,
+                                   uint32_t code_alignment,
+                                   uint64_t min_alignment,
+                                   struct pvr_pds_upload *const pds_upload_out)
 {
    struct pvr_device *const device = cmd_buffer->device;
    VkResult result;
index 157e528..8fcafdc 100644 (file)
@@ -1505,6 +1505,15 @@ VkResult pvr_cmd_buffer_alloc_mem(struct pvr_cmd_buffer *cmd_buffer,
                                   uint64_t size,
                                   uint32_t flags,
                                   struct pvr_bo **const pvr_bo_out);
+VkResult pvr_cmd_buffer_upload_pds(struct pvr_cmd_buffer *const cmd_buffer,
+                                   const uint32_t *data,
+                                   uint32_t data_size_dwords,
+                                   uint32_t data_alignment,
+                                   const uint32_t *code,
+                                   uint32_t code_size_dwords,
+                                   uint32_t code_alignment,
+                                   uint64_t min_alignment,
+                                   struct pvr_pds_upload *const pds_upload_out);
 
 void pvr_calculate_vertex_cam_size(const struct pvr_device_info *dev_info,
                                    const uint32_t vs_output_size,