diff --git a/src/gallium/drivers/radeonsi/si_cp_reg_shadowing.c b/src/gallium/drivers/radeonsi/si_cp_reg_shadowing.c index e7e27de04df..030e3f986b7 100644 --- a/src/gallium/drivers/radeonsi/si_cp_reg_shadowing.c +++ b/src/gallium/drivers/radeonsi/si_cp_reg_shadowing.c @@ -9,7 +9,7 @@ #include "ac_shadowed_regs.h" #include "util/u_memory.h" -void si_init_cp_reg_shadowing(struct si_context *sctx) +bool si_init_cp_reg_shadowing(struct si_context *sctx) { if (sctx->has_graphics && sctx->screen->info.has_kernelq_reg_shadowing) { @@ -26,12 +26,14 @@ void si_init_cp_reg_shadowing(struct si_context *sctx) PIPE_USAGE_DEFAULT, sctx->screen->info.fw_based_mcbp.csa_size, sctx->screen->info.fw_based_mcbp.csa_alignment); - if (!sctx->shadowing.registers || !sctx->shadowing.csa) + if (!sctx->shadowing.registers || !sctx->shadowing.csa) { mesa_loge("cannot create register shadowing buffer(s)"); - else + return false; + } else { sctx->ws->cs_set_mcbp_reg_shadowing_va(&sctx->gfx_cs, sctx->shadowing.registers->gpu_address, sctx->shadowing.csa->gpu_address); + } } else { sctx->shadowing.registers = si_aligned_buffer_create(sctx->b.screen, @@ -39,14 +41,17 @@ void si_init_cp_reg_shadowing(struct si_context *sctx) PIPE_USAGE_DEFAULT, SI_SHADOWED_REG_BUFFER_SIZE, 4096); - if (!sctx->shadowing.registers) + if (!sctx->shadowing.registers) { mesa_loge("cannot create a shadowed_regs buffer"); + return false; + } } } - si_init_gfx_preamble_state(sctx); + if (!si_init_gfx_preamble_state(sctx)) + return false; - if (sctx->shadowing.registers) { + if (sctx->has_graphics && sctx->screen->info.has_kernelq_reg_shadowing) { /* We need to clear the shadowed reg buffer. */ si_cp_dma_clear_buffer(sctx, &sctx->gfx_cs, &sctx->shadowing.registers->b.b, 0, sctx->shadowing.registers->bo_size, 0); @@ -58,6 +63,11 @@ void si_init_cp_reg_shadowing(struct si_context *sctx) sctx->shadowing.registers->gpu_address, sctx->screen->dpbb_allowed); + if (!shadowing_preamble) { + mesa_loge("failed to create shadowing_preamble"); + return false; + } + /* Initialize shadowed registers as follows. */ radeon_add_to_buffer_list(sctx, &sctx->gfx_cs, sctx->shadowing.registers, RADEON_USAGE_READWRITE | RADEON_PRIO_DESCRIPTORS); @@ -68,6 +78,11 @@ void si_init_cp_reg_shadowing(struct si_context *sctx) if (sctx->gfx_level < GFX11) { struct ac_pm4_state *clear_state = ac_emulate_clear_state(&sctx->screen->info); + if (!clear_state) { + ac_pm4_free_state(shadowing_preamble); + mesa_loge("failed to create clear_state"); + return false; + } si_pm4_emit_commands(sctx, clear_state); ac_pm4_free_state(clear_state); } @@ -92,4 +107,6 @@ void si_init_cp_reg_shadowing(struct si_context *sctx) shadowing_preamble->ndw); ac_pm4_free_state(shadowing_preamble); } + + return true; } diff --git a/src/gallium/drivers/radeonsi/si_pipe.c b/src/gallium/drivers/radeonsi/si_pipe.c index 639567b2506..ce2fc2d124a 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.c +++ b/src/gallium/drivers/radeonsi/si_pipe.c @@ -783,7 +783,8 @@ static struct pipe_context *si_create_context(struct pipe_screen *screen, unsign /* The remainder of this function initializes the gfx CS and must be last. */ assert(sctx->gfx_cs.current.cdw == 0); - si_init_cp_reg_shadowing(sctx); + if (!si_init_cp_reg_shadowing(sctx)) + goto fail; /* Set immutable fields of shader keys. */ if (sctx->gfx_level >= GFX9) { diff --git a/src/gallium/drivers/radeonsi/si_pipe.h b/src/gallium/drivers/radeonsi/si_pipe.h index f9f83e32955..ef6e9166a06 100644 --- a/src/gallium/drivers/radeonsi/si_pipe.h +++ b/src/gallium/drivers/radeonsi/si_pipe.h @@ -1559,7 +1559,7 @@ void si_cp_copy_data(struct si_context *sctx, struct radeon_cmdbuf *cs, unsigned struct si_resource *src, unsigned src_offset); /* si_cp_reg_shadowing.c */ -void si_init_cp_reg_shadowing(struct si_context *sctx); +bool si_init_cp_reg_shadowing(struct si_context *sctx); /* si_cp_utils.c */ void si_cp_release_mem_pws(struct si_context *sctx, struct radeon_cmdbuf *cs, diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index 990935cfc42..09569394e1f 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -5007,15 +5007,17 @@ static void si_init_graphics_preamble_state(struct si_context *sctx, } } -static void gfx6_init_gfx_preamble_state(struct si_context *sctx) +static bool gfx6_init_gfx_preamble_state(struct si_context *sctx) { struct si_screen *sscreen = sctx->screen; bool has_clear_state = sscreen->info.has_clear_state; /* We need more space because the preamble is large. */ struct si_pm4_state *pm4 = si_pm4_create_sized(sscreen, 214, sctx->has_graphics); - if (!pm4) - return; + if (!pm4) { + mesa_loge("failed to allocate memory for cs_preamble_state"); + return false; + } if (sctx->has_graphics && !sctx->shadowing.registers) { ac_pm4_cmd_add(&pm4->base, PKT3(PKT3_CONTEXT_CONTROL, 1, 0)); @@ -5070,31 +5072,38 @@ done: ac_pm4_finalize(&pm4->base); sctx->cs_preamble_state = pm4; sctx->cs_preamble_state_tmz = si_pm4_clone(sscreen, pm4); /* Make a copy of the preamble for TMZ. */ + return true; } -static void cdna_init_compute_preamble_state(struct si_context *sctx) +static bool cdna_init_compute_preamble_state(struct si_context *sctx) { struct si_screen *sscreen = sctx->screen; struct si_pm4_state *pm4 = si_pm4_create_sized(sscreen, 48, true); - if (!pm4) - return; + if (!pm4) { + mesa_loge("failed to allocate memory for cs_preamble_state"); + return false; + } si_init_compute_preamble_state(sctx, pm4); ac_pm4_finalize(&pm4->base); sctx->cs_preamble_state = pm4; sctx->cs_preamble_state_tmz = si_pm4_clone(sscreen, pm4); /* Make a copy of the preamble for TMZ. */ + + return true; } -static void gfx10_init_gfx_preamble_state(struct si_context *sctx) +static bool gfx10_init_gfx_preamble_state(struct si_context *sctx) { struct si_screen *sscreen = sctx->screen; /* We need more space because the preamble is large. */ struct si_pm4_state *pm4 = si_pm4_create_sized(sscreen, 214, sctx->has_graphics); - if (!pm4) - return; + if (!pm4) { + mesa_loge("failed to allocate memory for cs_preamble_state"); + return false; + } if (sctx->has_graphics && !sctx->shadowing.registers) { ac_pm4_cmd_add(&pm4->base, PKT3(PKT3_CONTEXT_CONTROL, 1, 0)); @@ -5155,15 +5164,18 @@ done: ac_pm4_finalize(&pm4->base); sctx->cs_preamble_state = pm4; sctx->cs_preamble_state_tmz = si_pm4_clone(sscreen, pm4); /* Make a copy of the preamble for TMZ. */ + return true; } -static void gfx12_init_gfx_preamble_state(struct si_context *sctx) +static bool gfx12_init_gfx_preamble_state(struct si_context *sctx) { struct si_screen *sscreen = sctx->screen; struct si_pm4_state *pm4 = si_pm4_create_sized(sscreen, 300, sctx->has_graphics); - if (!pm4) - return; + if (!pm4) { + mesa_loge("failed to allocate memory for cs_preamble_state"); + return false; + } if (sctx->has_graphics && !sctx->shadowing.registers) { ac_pm4_cmd_add(&pm4->base, PKT3(PKT3_CONTEXT_CONTROL, 1, 0)); @@ -5211,16 +5223,21 @@ static void gfx12_init_gfx_preamble_state(struct si_context *sctx) done: sctx->cs_preamble_state = pm4; sctx->cs_preamble_state_tmz = si_pm4_clone(sscreen, pm4); /* Make a copy of the preamble for TMZ. */ + return true; } -void si_init_gfx_preamble_state(struct si_context *sctx) +bool si_init_gfx_preamble_state(struct si_context *sctx) { + bool ret; + if (!sctx->screen->info.has_graphics) - cdna_init_compute_preamble_state(sctx); + ret = cdna_init_compute_preamble_state(sctx); else if (sctx->gfx_level >= GFX12) - gfx12_init_gfx_preamble_state(sctx); + ret = gfx12_init_gfx_preamble_state(sctx); else if (sctx->gfx_level >= GFX10) - gfx10_init_gfx_preamble_state(sctx); + ret = gfx10_init_gfx_preamble_state(sctx); else - gfx6_init_gfx_preamble_state(sctx); + ret = gfx6_init_gfx_preamble_state(sctx); + + return ret; } diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h index 1d750714eeb..924ac719dd6 100644 --- a/src/gallium/drivers/radeonsi/si_state.h +++ b/src/gallium/drivers/radeonsi/si_state.h @@ -628,7 +628,7 @@ void si_make_texture_descriptor(struct si_screen *screen, struct si_texture *tex void si_init_state_compute_functions(struct si_context *sctx); void si_init_state_functions(struct si_context *sctx); void si_init_screen_state_functions(struct si_screen *sscreen); -void si_init_gfx_preamble_state(struct si_context *sctx); +bool si_init_gfx_preamble_state(struct si_context *sctx); void si_make_buffer_descriptor(struct si_screen *screen, struct si_resource *buf, enum pipe_format format, unsigned offset, unsigned num_elements, uint32_t *state);