pvr: Add support for multiple emits from EOT program
authorJarred Davies <jarred.davies@imgtec.com>
Fri, 3 Mar 2023 12:01:19 +0000 (12:01 +0000)
committerMarge Bot <emma+marge@anholt.net>
Mon, 20 Mar 2023 14:35:19 +0000 (14:35 +0000)
Co-authored-by: Simon Perretta <simon.perretta@imgtec.com>
Signed-off-by: Jarred Davies <jarred.davies@imgtec.com>
Signed-off-by: Simon Perretta <simon.perretta@imgtec.com>
Reviewed-by: Karmjit Mahil <Karmjit.Mahil@imgtec.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21596>

src/imagination/rogue/passes/rogue_schedule_instr_groups.c
src/imagination/rogue/rogue_print.c
src/imagination/vulkan/pvr_cmd_buffer.c
src/imagination/vulkan/usc/pvr_uscgen.c
src/imagination/vulkan/usc/pvr_uscgen.h

index c4fb63d..2d7ead5 100644 (file)
@@ -286,6 +286,7 @@ static inline void rogue_instr_group_put(rogue_instr *instr,
 
    /* Set end flag. */
    group->header.end = instr->end;
+   instr->end = false;
 
    /* Ensure we're not mixing and matching execution conditions! */
    assert(group->header.exec_cond == ROGUE_EXEC_COND_INVALID ||
index 49edbe3..b8aa46b 100644 (file)
@@ -447,7 +447,7 @@ void rogue_print_instr(FILE *fp, const rogue_instr *instr)
    RESET(fp);
 
    if (instr->end)
-      fputs(".end", fp);
+      fputs(" {end}", fp);
 
    /* For debug purposes. */
    fputs(";", fp);
index 849e68e..348a645 100644 (file)
@@ -476,9 +476,13 @@ pvr_cmd_buffer_upload_pds_data(struct pvr_cmd_buffer *const cmd_buffer,
                                     pds_upload_out);
 }
 
+/* pbe_cs_words must be an array of length emit_count with
+ * ROGUE_NUM_PBESTATE_STATE_WORDS entries
+ */
 static VkResult pvr_sub_cmd_gfx_per_job_fragment_programs_create_and_upload(
    struct pvr_cmd_buffer *const cmd_buffer,
-   const uint32_t pbe_cs_words[static const ROGUE_NUM_PBESTATE_STATE_WORDS],
+   const uint32_t emit_count,
+   const uint32_t *pbe_cs_words,
    struct pvr_pds_upload *const pds_upload_out)
 {
    struct pvr_pds_event_program pixel_event_program = {
@@ -495,8 +499,10 @@ static VkResult pvr_sub_cmd_gfx_per_job_fragment_programs_create_and_upload(
    uint32_t usc_temp_count;
    VkResult result;
 
-   pvr_uscgen_per_job_eot(pbe_cs_words[0],
-                          pbe_cs_words[1],
+   assert(emit_count > 0);
+
+   pvr_uscgen_per_job_eot(emit_count,
+                          pbe_cs_words,
                           &usc_temp_count,
                           &eot_program_bin);
 
@@ -1237,10 +1243,9 @@ static VkResult pvr_sub_cmd_gfx_job_init(const struct pvr_device_info *dev_info,
           emit_state.pbe_reg_words,
           sizeof(emit_state.pbe_reg_words));
 
-   /* FIXME: The fragment program only supports a single surface at present. */
-   assert(emit_state.emit_count == 1);
    result = pvr_sub_cmd_gfx_per_job_fragment_programs_create_and_upload(
       cmd_buffer,
+      emit_state.emit_count,
       emit_state.pbe_cs_words[0],
       &pds_pixel_event_program);
    if (result != VK_SUCCESS)
index 6c89c5d..abae592 100644 (file)
 
 #include <stdbool.h>
 
-void pvr_uscgen_per_job_eot(uint32_t state0,
-                            uint32_t state1,
+void pvr_uscgen_per_job_eot(uint32_t emit_count,
+                            const uint32_t *emit_state, /* Expects emit_count *
+                                                           ROGUE_NUM_PBESTATE_STATE_WORDS
+                                                           entries */
                             unsigned *temps_used,
                             struct util_dynarray *binary)
 {
    rogue_builder b;
    rogue_shader *shader = rogue_shader_create(NULL, MESA_SHADER_NONE);
+   rogue_reg *state_word_0 = rogue_temp_reg(shader, 0);
+   rogue_reg *state_word_1 = rogue_temp_reg(shader, 1);
+   rogue_backend_instr *emitpix = NULL;
+
    rogue_set_shader_name(shader, "per-job EOT");
    rogue_builder_init(&b, shader);
    rogue_push_block(&b);
 
-   rogue_reg *state_word_0 = rogue_ssa_reg(shader, 0);
-   rogue_reg *state_word_1 = rogue_ssa_reg(shader, 1);
+   for (unsigned u = 0; u < emit_count; u++) {
+      if (u > 0)
+         rogue_WOP(&b);
 
-   rogue_MOV(&b, rogue_ref_reg(state_word_0), rogue_ref_imm(state0));
-   rogue_MOV(&b, rogue_ref_reg(state_word_1), rogue_ref_imm(state1));
+      rogue_MOV(&b, rogue_ref_reg(state_word_0), rogue_ref_imm(emit_state[0]));
+      rogue_MOV(&b, rogue_ref_reg(state_word_1), rogue_ref_imm(emit_state[1]));
 
-   rogue_backend_instr *emitpix = rogue_EMITPIX(&b,
-                                                rogue_ref_reg(state_word_0),
-                                                rogue_ref_reg(state_word_1));
-   rogue_set_backend_op_mod(emitpix, ROGUE_BACKEND_OP_MOD_FREEP);
+      emitpix = rogue_EMITPIX(&b,
+                              rogue_ref_reg(state_word_0),
+                              rogue_ref_reg(state_word_1));
 
-   rogue_END(&b);
+      emit_state += 2;
+   }
+
+   assert(emitpix);
+
+   rogue_set_backend_op_mod(emitpix, ROGUE_BACKEND_OP_MOD_FREEP);
+   emitpix->instr.end = true;
 
    rogue_shader_passes(shader);
    rogue_encode_shader(NULL, shader, binary);
index 3918983..396d3f3 100644 (file)
@@ -30,8 +30,8 @@
 
 /* TODO: Shader caching (not pipeline caching) support. */
 
-void pvr_uscgen_per_job_eot(uint32_t state0,
-                            uint32_t state1,
+void pvr_uscgen_per_job_eot(uint32_t emit_count,
+                            const uint32_t *emit_state,
                             unsigned *temps_used,
                             struct util_dynarray *binary);