radeonsi: add initial aco compile code

Only for monolithic PS.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Signed-off-by: Qiang Yu <yuq825@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22573>
This commit is contained in:
Qiang Yu 2023-04-14 17:21:45 +08:00 committed by Marge Bot
parent 91c91bb972
commit 6a360e4a71
4 changed files with 141 additions and 8 deletions

View file

@ -52,6 +52,7 @@ files_libradeonsi = files(
'si_sdma_copy_image.c',
'si_shader.c',
'si_shader.h',
'si_shader_aco.c',
'si_shader_info.c',
'si_shader_internal.h',
'si_shader_llvm.c',
@ -104,7 +105,7 @@ files_libradeonsi = files(
)
radeonsi_include_dirs = [inc_src, inc_include, inc_gallium, inc_gallium_aux, inc_amd_common,
inc_amd_common_llvm, inc_gallium_drivers]
inc_amd_common_llvm, inc_gallium_drivers, inc_compiler]
radeonsi_deps = [dep_llvm, dep_clock, dep_libdrm_radeon, idep_nir_headers, idep_amdgfxregs_h, idep_mesautil, idep_aco]
radeonsi_gfx_libs = []

View file

@ -2621,14 +2621,11 @@ bool si_compile_shader(struct si_screen *sscreen, struct ac_llvm_compiler *compi
FLOAT_CONTROLS_DENORM_FLUSH_TO_ZERO_FP64))
float_mode &= ~V_00B028_FP_16_64_DENORMS;
/* TODO: ACO could compile non-monolithic shaders here (starting
* with PS and NGG VS), but monolithic shaders should be compiled
* by LLVM due to more complicated compilation.
*/
if (!si_llvm_compile_shader(sscreen, compiler, shader, &args, debug, nir)) {
ret = false;
ret = shader->use_aco ?
si_aco_compile_shader(shader, &args, nir, debug) :
si_llvm_compile_shader(sscreen, compiler, shader, &args, debug, nir);
if (!ret)
goto out;
}
shader->config.float_mode = float_mode;

View file

@ -0,0 +1,129 @@
/*
* Copyright 2023 Advanced Micro Devices, Inc.
* All Rights Reserved.
*
* 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
* on the rights to use, copy, modify, merge, publish, distribute, sub
* license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL
* THE AUTHOR(S) AND/OR THEIR SUPPLIERS 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 "si_shader_internal.h"
#include "si_pipe.h"
#include "aco_interface.h"
static void
si_aco_compiler_debug(void *private_data, enum aco_compiler_debug_level level,
const char *message)
{
struct util_debug_callback *debug = private_data;
util_debug_message(debug, SHADER_INFO, "%s\n", message);
}
static void
si_fill_aco_options(struct si_shader *shader, struct aco_compiler_options *options,
struct util_debug_callback *debug)
{
const struct si_shader_selector *sel = shader->selector;
options->dump_shader =
si_can_dump_shader(sel->screen, sel->stage, SI_DUMP_ACO_IR) ||
si_can_dump_shader(sel->screen, sel->stage, SI_DUMP_ASM);
options->dump_preoptir = si_can_dump_shader(sel->screen, sel->stage, SI_DUMP_INIT_ACO_IR);
options->record_ir = sel->screen->record_llvm_ir;
options->load_grid_size_from_user_sgpr = true;
options->family = sel->screen->info.family;
options->gfx_level = sel->screen->info.gfx_level;
options->address32_hi = sel->screen->info.address32_hi;
options->debug.func = si_aco_compiler_debug;
options->debug.private_data = debug;
}
static void
si_fill_aco_shader_info(struct si_shader *shader, struct aco_shader_info *info)
{
const struct si_shader_selector *sel = shader->selector;
info->wave_size = shader->wave_size;
info->workgroup_size = si_get_max_workgroup_size(shader);
/* aco need non-zero value */
if (!info->workgroup_size)
info->workgroup_size = info->wave_size;
info->image_2d_view_of_3d = sel->screen->info.gfx_level == GFX9;
switch (sel->stage) {
case MESA_SHADER_FRAGMENT:
info->ps.num_interp = si_get_ps_num_interp(shader);
info->ps.spi_ps_input = shader->config.spi_ps_input_ena;
break;
default:
break;
}
}
static void
si_aco_build_shader_binary(void **data, const struct ac_shader_config *config,
const char *llvm_ir_str, unsigned llvm_ir_size, const char *disasm_str,
unsigned disasm_size, uint32_t *statistics, uint32_t stats_size,
uint32_t exec_size, const uint32_t *code, uint32_t code_dw,
const struct aco_symbol *symbols, unsigned num_symbols)
{
struct si_shader *shader = (struct si_shader *)data;
unsigned code_size = code_dw * 4;
char *buffer = MALLOC(code_size + disasm_size);
memcpy(buffer, code, code_size);
shader->binary.type = SI_SHADER_BINARY_RAW;
shader->binary.code_buffer = buffer;
shader->binary.code_size = code_size;
if (disasm_size) {
memcpy(buffer + code_size, disasm_str, disasm_size);
shader->binary.disasm_string = buffer + code_size;
shader->binary.disasm_size = disasm_size;
}
if (llvm_ir_size) {
shader->binary.llvm_ir_string = MALLOC(llvm_ir_size);
memcpy(shader->binary.llvm_ir_string, llvm_ir_str, llvm_ir_size);
}
shader->config = *config;
}
bool
si_aco_compile_shader(struct si_shader *shader,
struct si_shader_args *args,
struct nir_shader *nir,
struct util_debug_callback *debug)
{
struct aco_compiler_options options = {0};
si_fill_aco_options(shader, &options, debug);
struct aco_shader_info info = {0};
si_fill_aco_shader_info(shader, &info);
aco_compile_shader(&options, &info, 1, &nir, &args->ac,
si_aco_build_shader_binary, (void **)shader);
return true;
}

View file

@ -239,4 +239,10 @@ void si_llvm_ps_build_end(struct si_shader_context *ctx);
void si_llvm_build_vs_prolog(struct si_shader_context *ctx, union si_shader_part_key *key,
bool separate_prolog);
/* si_shader_aco.c */
bool si_aco_compile_shader(struct si_shader *shader,
struct si_shader_args *args,
struct nir_shader *nir,
struct util_debug_callback *debug);
#endif