pvr: Add support for multiple emits from EOT program

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>
This commit is contained in:
Jarred Davies 2023-03-03 12:01:19 +00:00 committed by Marge Bot
parent 4162c37d57
commit 26671b5d63
5 changed files with 37 additions and 19 deletions

View 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 ||

View 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);

View 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)

View File

@ -29,29 +29,41 @@
#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]));
emitpix = rogue_EMITPIX(&b,
rogue_ref_reg(state_word_0),
rogue_ref_reg(state_word_1));
emit_state += 2;
}
assert(emitpix);
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);
rogue_END(&b);
emitpix->instr.end = true;
rogue_shader_passes(shader);
rogue_encode_shader(NULL, shader, binary);

View 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);