Mesa (main): pvr: Change compute hard coding infrastructure.

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Jun 20 08:20:41 UTC 2022


Module: Mesa
Branch: main
Commit: 66f4c9abc9d54ae76e107e824df9bb3f0051d493
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=66f4c9abc9d54ae76e107e824df9bb3f0051d493

Author: Karmjit Mahil <Karmjit.Mahil at imgtec.com>
Date:   Wed Jun  1 15:04:59 2022 +0100

pvr: Change compute hard coding infrastructure.

This commit changes the way in which the hard coding is done in
the compute pipeline to allow easier hard coding for demos other
than the simple-compute demo.

Signed-off-by: Karmjit Mahil <Karmjit.Mahil at imgtec.com>
Acked-by: Alyssa Rosenzweig <alyssa at collabora.com>
Reviewed-by: Frank Binns <frank.binns at imgtec.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16999>

---

 src/imagination/vulkan/meson.build                 |   1 +
 src/imagination/vulkan/pvr_hardcode.c              | 145 +++++++++++++++++++++
 src/imagination/vulkan/pvr_hardcode.h              |  71 ++++++++++
 src/imagination/vulkan/pvr_pipeline.c              | 125 +++++++-----------
 src/imagination/vulkan/pvr_private.h               |   5 +-
 .../pvr_simple_compute.h}                          |   8 +-
 6 files changed, 269 insertions(+), 86 deletions(-)

diff --git a/src/imagination/vulkan/meson.build b/src/imagination/vulkan/meson.build
index 3b978dd4f33..577f8e06ea4 100644
--- a/src/imagination/vulkan/meson.build
+++ b/src/imagination/vulkan/meson.build
@@ -43,6 +43,7 @@ pvr_files = files(
   'pvr_descriptor_set.c',
   'pvr_device.c',
   'pvr_formats.c',
+  'pvr_hardcode.c',
   'pvr_hw_pass.c',
   'pvr_image.c',
   'pvr_job_common.c',
diff --git a/src/imagination/vulkan/pvr_hardcode.c b/src/imagination/vulkan/pvr_hardcode.c
new file mode 100644
index 00000000000..1091cf4eb02
--- /dev/null
+++ b/src/imagination/vulkan/pvr_hardcode.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright © 2022 Imagination Technologies Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <vulkan/vulkan_core.h>
+
+#include "hwdef/rogue_hw_utils.h"
+#include "pvr_hardcode.h"
+#include "pvr_private.h"
+#include "rogue/rogue.h"
+#include "usc/hardcoded_apps/pvr_simple_compute.h"
+#include "util/macros.h"
+#include "util/u_process.h"
+
+/**
+ * \file pvr_hardcode.c
+ *
+ * \brief Contains hard coding functions.
+ * This should eventually be deleted as the compiler becomes more capable.
+ */
+
+/* Applications for which the compiler is capable of generating valid shaders.
+ */
+static const char *const compilable_progs[] = {
+   "triangle",
+};
+
+static const struct pvr_hard_coding_data {
+   const char *const name;
+
+   union {
+      struct {
+         const uint8_t *const shader;
+         size_t shader_size;
+
+         /* Note that the bo field will be unused. */
+         const struct pvr_compute_pipeline_shader_state shader_info;
+
+         const struct pvr_hard_code_compute_build_info build_info;
+      } compute;
+   };
+
+} hard_coding_table[] = {
+   {
+      .name = "simple-compute",
+      .compute = {
+         .shader = pvr_simple_compute_shader,
+         .shader_size = sizeof(pvr_simple_compute_shader),
+
+         .shader_info = {
+            .uses_atomic_ops = false,
+            .uses_barrier = false,
+            .uses_num_workgroups = false,
+
+            .const_shared_reg_count = 4,
+            .input_register_count = 8,
+            .work_size = 1 * 1 * 1,
+            .coefficient_register_count = 4,
+         },
+
+         .build_info = {
+            .ubo_data = { 0 },
+
+            .local_invocation_regs = { 0, 1 },
+            .work_group_regs = { 0, 1, 2 },
+            .barrier_reg = ROGUE_REG_UNUSED,
+            .usc_temps = 0,
+
+            .explicit_conts_usage = {
+               .start_offset = 0,
+            },
+         },
+      }
+   },
+};
+
+bool pvr_hard_code_shader_required(void)
+{
+   const char *const program = util_get_process_name();
+
+   for (uint32_t i = 0; i < ARRAY_SIZE(compilable_progs); i++) {
+      if (strcmp(program, compilable_progs[i]) == 0)
+         return false;
+   }
+
+   return true;
+}
+
+static const struct pvr_hard_coding_data *pvr_get_hard_coding_data()
+{
+   const char *const program = util_get_process_name();
+
+   for (uint32_t i = 0; i < ARRAY_SIZE(hard_coding_table); i++) {
+      if (strcmp(program, hard_coding_table[i].name) == 0)
+         return &hard_coding_table[i];
+   }
+
+   mesa_loge("Could not find hard coding data for %s", program);
+
+   return NULL;
+}
+
+VkResult pvr_hard_code_compute_pipeline(
+   struct pvr_device *const device,
+   struct pvr_compute_pipeline_shader_state *const shader_state_out,
+   struct pvr_hard_code_compute_build_info *const build_info_out)
+{
+   const uint32_t cache_line_size =
+      rogue_get_slc_cache_line_size(&device->pdevice->dev_info);
+   const struct pvr_hard_coding_data *const data = pvr_get_hard_coding_data();
+
+   mesa_logd("Hard coding compute pipeline for %s", data->name);
+
+   *build_info_out = data->compute.build_info;
+   *shader_state_out = data->compute.shader_info;
+
+   return pvr_gpu_upload_usc(device,
+                             data->compute.shader,
+                             data->compute.shader_size,
+                             cache_line_size,
+                             &shader_state_out->bo);
+}
diff --git a/src/imagination/vulkan/pvr_hardcode.h b/src/imagination/vulkan/pvr_hardcode.h
new file mode 100644
index 00000000000..c663eb76f10
--- /dev/null
+++ b/src/imagination/vulkan/pvr_hardcode.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright © 2022 Imagination Technologies Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef PVR_HARDCODE_SHADERS_H
+#define PVR_HARDCODE_SHADERS_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <vulkan/vulkan_core.h>
+
+#include "rogue/rogue_build_data.h"
+
+/**
+ * \file pvr_hardcode.h
+ *
+ * \brief Contains hard coding functions.
+ * This should eventually be deleted as the compiler becomes more capable.
+ */
+
+struct pvr_compute_pipeline_shader_state;
+struct pvr_device;
+
+struct pvr_explicit_constant_usage {
+   /* Hardware register number assigned to the explicit constant with the lower
+    * pre_assigned offset.
+    */
+   uint32_t start_offset;
+};
+
+struct pvr_hard_code_compute_build_info {
+   struct rogue_ubo_data ubo_data;
+
+   uint32_t local_invocation_regs[2];
+   uint32_t work_group_regs[3];
+   uint32_t barrier_reg;
+   uint32_t usc_temps;
+
+   struct pvr_explicit_constant_usage explicit_conts_usage;
+};
+
+/* Returns true if the shader for the currently running program requires hard
+ * coded shaders.
+ */
+bool pvr_hard_code_shader_required(void);
+
+VkResult pvr_hard_code_compute_pipeline(
+   struct pvr_device *const device,
+   struct pvr_compute_pipeline_shader_state *const shader_state_out,
+   struct pvr_hard_code_compute_build_info *const build_info_out);
+
+#endif /* PVR_HARDCODE_SHADERS_H */
diff --git a/src/imagination/vulkan/pvr_pipeline.c b/src/imagination/vulkan/pvr_pipeline.c
index 97772100cf2..e767868e868 100644
--- a/src/imagination/vulkan/pvr_pipeline.c
+++ b/src/imagination/vulkan/pvr_pipeline.c
@@ -36,10 +36,10 @@
 #include "pvr_bo.h"
 #include "pvr_csb.h"
 #include "pvr_csb_enum_helpers.h"
+#include "pvr_hardcode.h"
 #include "pvr_pds.h"
 #include "pvr_private.h"
 #include "pvr_shader.h"
-#include "pvr_usc_compute_shader.h"
 #include "pvr_winsys.h"
 #include "rogue/rogue.h"
 #include "rogue/rogue_build_data.h"
@@ -52,37 +52,6 @@
 #include "vk_object.h"
 #include "vk_util.h"
 
-/* FIXME: Remove this when the compiler is hooked up. */
-/******************************************************************************
-   Hard coding
- ******************************************************************************/
-/* This section contains hard coding related structs. */
-
-struct pvr_explicit_constant_usage {
-   /* Hardware register number assigned to the explicit constant with the lower
-    * pre_assigned offset.
-    */
-   uint32_t start_offset;
-};
-
-static const struct {
-   uint32_t local_invocation_regs[2];
-
-   uint32_t work_group_regs[PVR_WORKGROUP_DIMENSIONS];
-
-   uint32_t barrier_reg;
-
-   uint32_t usc_temps;
-} pvr_pds_compute_program_params = {
-   .local_invocation_regs = { 0, 1 },
-
-   .work_group_regs = { 0, 1, 2 },
-
-   .barrier_reg = ROGUE_REG_UNUSED,
-
-   .usc_temps = 0,
-};
-
 /*****************************************************************************
    PDS functions
 *****************************************************************************/
@@ -1043,42 +1012,58 @@ static VkResult pvr_compute_pipeline_compile(
    const VkAllocationCallbacks *const allocator,
    struct pvr_compute_pipeline *const compute_pipeline)
 {
-   /* FIXME: Remove this hard coding. */
-   const struct pvr_explicit_constant_usage explicit_const_usage = {
-      .start_offset = 0,
-   };
-   const struct rogue_ubo_data uniform_program_ubo_data = { 0 };
-
-   const uint32_t cache_line_size =
-      rogue_get_slc_cache_line_size(&device->pdevice->dev_info);
    uint32_t work_group_input_regs[PVR_WORKGROUP_DIMENSIONS];
+   struct pvr_explicit_constant_usage explicit_const_usage;
    uint32_t local_input_regs[PVR_WORKGROUP_DIMENSIONS];
+   struct rogue_ubo_data ubo_data;
    uint32_t barrier_coefficient;
+   uint32_t usc_temps;
    VkResult result;
 
-   /* FIXME: Compile the shader. */
+   if (pvr_hard_code_shader_required()) {
+      struct pvr_hard_code_compute_build_info build_info;
 
-   /* FIXME: Remove this hard coding. */
-   compute_pipeline->state.shader.uses_atomic_ops = false;
-   compute_pipeline->state.shader.uses_barrier = false;
-   compute_pipeline->state.shader.uses_num_workgroups = false;
-   compute_pipeline->state.shader.const_shared_reg_count = 4;
-   compute_pipeline->state.shader.input_register_count = 8;
-   compute_pipeline->state.shader.work_size = 1 * 1 * 1;
-   compute_pipeline->state.shader.coefficient_register_count = 4;
+      result = pvr_hard_code_compute_pipeline(device,
+                                              &compute_pipeline->state.shader,
+                                              &build_info);
+      if (result != VK_SUCCESS)
+         return result;
 
-   result = pvr_gpu_upload_usc(device,
-                               pvr_usc_compute_shader,
-                               sizeof(pvr_usc_compute_shader),
-                               cache_line_size,
-                               &compute_pipeline->state.shader.bo);
-   if (result != VK_SUCCESS)
-      return result;
+      ubo_data = build_info.ubo_data;
+
+      /* We make sure that the compiler's unused reg value is compatible with
+       * the pds api.
+       */
+      STATIC_ASSERT(ROGUE_REG_UNUSED == PVR_PDS_COMPUTE_INPUT_REG_UNUSED);
+
+      barrier_coefficient = build_info.barrier_reg;
+
+      /* TODO: Maybe change the pds api to use pointers so we avoid the copy. */
+      local_input_regs[0] = build_info.local_invocation_regs[0];
+      local_input_regs[1] = build_info.local_invocation_regs[1];
+      /* This is not a mistake. We want to assign element 1 to 2. */
+      local_input_regs[2] = build_info.local_invocation_regs[1];
+
+      STATIC_ASSERT(
+         __same_type(work_group_input_regs, build_info.work_group_regs));
+      typed_memcpy(work_group_input_regs,
+                   build_info.work_group_regs,
+                   PVR_WORKGROUP_DIMENSIONS);
+
+      usc_temps = build_info.usc_temps;
+
+      explicit_const_usage = build_info.explicit_conts_usage;
+
+   } else {
+      /* FIXME: Compile and upload the shader. */
+      /* FIXME: Initialize the shader state and setup build info. */
+      abort();
+   };
 
    result = pvr_pds_uniform_program_create_and_upload(
       device,
       allocator,
-      &uniform_program_ubo_data,
+      &ubo_data,
       &explicit_const_usage,
       compute_pipeline->base.layout,
       PVR_STAGE_ALLOCATION_COMPUTE,
@@ -1087,35 +1072,13 @@ static VkResult pvr_compute_pipeline_compile(
    if (result != VK_SUCCESS)
       goto err_free_shader;
 
-   /* We make sure that the compiler's unused reg value is compatible with the
-    * pds api.
-    */
-   STATIC_ASSERT(ROGUE_REG_UNUSED == PVR_PDS_COMPUTE_INPUT_REG_UNUSED);
-
-   barrier_coefficient = pvr_pds_compute_program_params.barrier_reg;
-
-   /* TODO: Maybe change the pds api to use pointers so we avoid the copy. */
-   local_input_regs[0] =
-      pvr_pds_compute_program_params.local_invocation_regs[0];
-   local_input_regs[1] =
-      pvr_pds_compute_program_params.local_invocation_regs[1];
-   /* This is not a mistake. We want to assign element 1 to 2. */
-   local_input_regs[2] =
-      pvr_pds_compute_program_params.local_invocation_regs[1];
-
-   STATIC_ASSERT(__same_type(work_group_input_regs,
-                             pvr_pds_compute_program_params.work_group_regs));
-   typed_memcpy(work_group_input_regs,
-                pvr_pds_compute_program_params.work_group_regs,
-                PVR_WORKGROUP_DIMENSIONS);
-
    result = pvr_pds_compute_program_create_and_upload(
       device,
       allocator,
       local_input_regs,
       work_group_input_regs,
       barrier_coefficient,
-      pvr_pds_compute_program_params.usc_temps,
+      usc_temps,
       compute_pipeline->state.shader.bo->vma->dev_addr,
       &compute_pipeline->state.primary_program,
       &compute_pipeline->state.primary_program_info);
@@ -1137,7 +1100,7 @@ static VkResult pvr_compute_pipeline_compile(
          local_input_regs,
          work_group_input_regs,
          barrier_coefficient,
-         pvr_pds_compute_program_params.usc_temps,
+         usc_temps,
          compute_pipeline->state.shader.bo->vma->dev_addr,
          &compute_pipeline->state.primary_base_workgroup_variant_program);
       if (result != VK_SUCCESS)
diff --git a/src/imagination/vulkan/pvr_private.h b/src/imagination/vulkan/pvr_private.h
index 4b687db05f0..64130d7cebe 100644
--- a/src/imagination/vulkan/pvr_private.h
+++ b/src/imagination/vulkan/pvr_private.h
@@ -1037,7 +1037,10 @@ struct pvr_compute_pipeline {
    struct pvr_pipeline base;
 
    struct {
-      struct {
+      /* TODO: Change this to be an anonymous struct once the shader hardcoding
+       * is removed.
+       */
+      struct pvr_compute_pipeline_shader_state {
          /* Pointer to a buffer object that contains the shader binary. */
          struct pvr_bo *bo;
 
diff --git a/src/imagination/vulkan/usc/programs/pvr_usc_compute_shader.h b/src/imagination/vulkan/usc/hardcoded_apps/pvr_simple_compute.h
similarity index 95%
rename from src/imagination/vulkan/usc/programs/pvr_usc_compute_shader.h
rename to src/imagination/vulkan/usc/hardcoded_apps/pvr_simple_compute.h
index 0d59c7577ff..9c79e27d2d4 100644
--- a/src/imagination/vulkan/usc/programs/pvr_usc_compute_shader.h
+++ b/src/imagination/vulkan/usc/hardcoded_apps/pvr_simple_compute.h
@@ -23,13 +23,13 @@
 
 /* Auto-generated file - don't edit */
 
-#ifndef PVR_USC_COMPUTE_SHADER_H
-#define PVR_USC_COMPUTE_SHADER_H
+#ifndef PVR_SIMPLE_COMPUTE_H
+#define PVR_SIMPLE_COMPUTE_H
 
 #include <stdint.h>
 
 /* clang-format off */
-uint8_t pvr_usc_compute_shader[] = {
+static const uint8_t pvr_simple_compute_shader[] = {
    0x44, 0x12, 0xd3, 0x3f,
    0x00, 0x00, 0x00, 0x24,
    0x46, 0x40, 0xf9, 0xb0,
@@ -99,4 +99,4 @@ uint8_t pvr_usc_compute_shader[] = {
 };
 /* clang-format on */
 
-#endif /* PVR_USC_COMPUTE_SHADER_H */
+#endif /* PVR_SIMPLE_COMPUTE_H */



More information about the mesa-commit mailing list