2024-07-12 13:52:46 -07:00
|
|
|
/*
|
|
|
|
|
* Copyright © 2010 Intel Corporation
|
|
|
|
|
* SPDX-License-Identifier: MIT
|
|
|
|
|
*/
|
|
|
|
|
|
2024-12-06 19:48:54 -08:00
|
|
|
#include "brw_analysis.h"
|
2025-02-05 14:25:15 -08:00
|
|
|
#include "brw_shader.h"
|
2024-12-06 16:17:46 -08:00
|
|
|
#include "brw_generator.h"
|
2024-07-12 13:52:46 -07:00
|
|
|
#include "brw_nir.h"
|
|
|
|
|
#include "brw_cfg.h"
|
|
|
|
|
#include "brw_private.h"
|
|
|
|
|
#include "intel_nir.h"
|
|
|
|
|
#include "shader_enums.h"
|
|
|
|
|
#include "dev/intel_debug.h"
|
|
|
|
|
#include "dev/intel_wa.h"
|
|
|
|
|
|
|
|
|
|
#include <memory>
|
|
|
|
|
|
|
|
|
|
static uint64_t
|
|
|
|
|
brw_bsr(const struct intel_device_info *devinfo,
|
2025-01-29 11:05:49 -08:00
|
|
|
uint32_t offset, uint8_t simd_size, uint8_t local_arg_offset,
|
|
|
|
|
uint8_t grf_used)
|
2024-07-12 13:52:46 -07:00
|
|
|
{
|
|
|
|
|
assert(offset % 64 == 0);
|
|
|
|
|
assert(simd_size == 8 || simd_size == 16);
|
|
|
|
|
assert(local_arg_offset % 8 == 0);
|
|
|
|
|
|
2025-01-29 11:05:49 -08:00
|
|
|
return ((uint64_t)ptl_register_blocks(grf_used) << 60) |
|
|
|
|
|
offset |
|
2024-07-12 13:52:46 -07:00
|
|
|
SET_BITS(simd_size == 8, 4, 4) |
|
|
|
|
|
SET_BITS(local_arg_offset / 8, 2, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-12 14:20:57 -07:00
|
|
|
static bool
|
2024-12-07 10:25:45 -08:00
|
|
|
run_bs(brw_shader &s, bool allow_spilling)
|
2024-07-12 14:20:57 -07:00
|
|
|
{
|
|
|
|
|
assert(s.stage >= MESA_SHADER_RAYGEN && s.stage <= MESA_SHADER_CALLABLE);
|
|
|
|
|
|
2024-12-06 22:13:36 -08:00
|
|
|
s.payload_ = new brw_bs_thread_payload(s);
|
2024-07-12 14:20:57 -07:00
|
|
|
|
2024-12-07 09:36:03 -08:00
|
|
|
brw_from_nir(&s);
|
2024-07-12 14:20:57 -07:00
|
|
|
|
|
|
|
|
if (s.failed)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
/* TODO(RT): Perhaps rename this? */
|
|
|
|
|
s.emit_cs_terminate();
|
|
|
|
|
|
2024-07-12 17:08:46 -07:00
|
|
|
brw_calculate_cfg(s);
|
2024-07-12 14:20:57 -07:00
|
|
|
|
2024-12-06 11:37:57 -08:00
|
|
|
brw_optimize(s);
|
2024-07-12 14:20:57 -07:00
|
|
|
|
|
|
|
|
s.assign_curb_setup();
|
|
|
|
|
|
2024-12-06 11:37:57 -08:00
|
|
|
brw_lower_3src_null_dest(s);
|
|
|
|
|
brw_workaround_emit_dummy_mov_instruction(s);
|
2024-07-12 14:20:57 -07:00
|
|
|
|
2024-07-12 16:55:33 -07:00
|
|
|
brw_allocate_registers(s, allow_spilling);
|
2024-07-12 14:20:57 -07:00
|
|
|
|
2024-12-06 11:37:57 -08:00
|
|
|
brw_workaround_source_arf_before_eot(s);
|
2024-10-19 12:53:21 +03:00
|
|
|
|
2024-07-12 14:20:57 -07:00
|
|
|
return !s.failed;
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-12 13:52:46 -07:00
|
|
|
static uint8_t
|
|
|
|
|
compile_single_bs(const struct brw_compiler *compiler,
|
|
|
|
|
struct brw_compile_bs_params *params,
|
|
|
|
|
const struct brw_bs_prog_key *key,
|
|
|
|
|
struct brw_bs_prog_data *prog_data,
|
|
|
|
|
nir_shader *shader,
|
2024-12-06 16:33:35 -08:00
|
|
|
brw_generator *g,
|
2024-07-12 13:52:46 -07:00
|
|
|
struct brw_compile_stats *stats,
|
2025-01-29 11:05:49 -08:00
|
|
|
int *prog_offset,
|
|
|
|
|
uint64_t *bsr)
|
2024-07-12 13:52:46 -07:00
|
|
|
{
|
2025-05-16 23:28:04 +00:00
|
|
|
const bool debug_enabled = brw_should_print_shader(shader, DEBUG_RT, params->base.source_hash);
|
2024-07-12 13:52:46 -07:00
|
|
|
|
|
|
|
|
prog_data->max_stack_size = MAX2(prog_data->max_stack_size,
|
|
|
|
|
shader->scratch_size);
|
|
|
|
|
|
2025-06-27 08:07:03 -07:00
|
|
|
/* Since divergence is a lot more likely in RT than compute, it makes
|
|
|
|
|
* sense to limit ourselves to the smallest available SIMD for now.
|
|
|
|
|
*/
|
|
|
|
|
const unsigned required_width = compiler->devinfo->ver >= 20 ? 16u : 8u;
|
|
|
|
|
|
|
|
|
|
brw_nir_apply_key(shader, compiler, &key->base, required_width);
|
2024-07-12 13:52:46 -07:00
|
|
|
brw_postprocess_nir(shader, compiler, debug_enabled,
|
|
|
|
|
key->base.robust_flags);
|
|
|
|
|
|
2025-06-27 08:46:56 -07:00
|
|
|
brw_shader s(compiler, ¶ms->base, &key->base, &prog_data->base, shader,
|
|
|
|
|
required_width, stats != NULL, debug_enabled);
|
2024-07-12 13:52:46 -07:00
|
|
|
|
2025-06-27 08:46:56 -07:00
|
|
|
const bool allow_spilling = true;
|
|
|
|
|
if (!run_bs(s, allow_spilling)) {
|
2024-07-12 13:52:46 -07:00
|
|
|
params->base.error_str =
|
|
|
|
|
ralloc_asprintf(params->base.mem_ctx,
|
2025-06-27 08:46:56 -07:00
|
|
|
"Can't compile shader: '%s'.\n",
|
|
|
|
|
s.fail_msg);
|
2024-07-12 13:52:46 -07:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-27 08:46:56 -07:00
|
|
|
int offset = g->generate_code(s.cfg, s.dispatch_width, s.shader_stats,
|
|
|
|
|
s.performance_analysis.require(), stats);
|
2024-07-12 13:52:46 -07:00
|
|
|
if (prog_offset)
|
|
|
|
|
*prog_offset = offset;
|
|
|
|
|
else
|
|
|
|
|
assert(offset == 0);
|
|
|
|
|
|
2025-01-29 11:05:49 -08:00
|
|
|
if (bsr)
|
2025-06-27 08:46:56 -07:00
|
|
|
*bsr = brw_bsr(compiler->devinfo, offset, s.dispatch_width, 0,
|
|
|
|
|
s.grf_used);
|
2025-01-29 11:05:49 -08:00
|
|
|
else
|
2024-09-18 14:32:58 -07:00
|
|
|
prog_data->base.grf_used = MAX2(prog_data->base.grf_used,
|
2025-06-27 08:46:56 -07:00
|
|
|
s.grf_used);
|
2024-09-18 14:32:58 -07:00
|
|
|
|
2025-06-27 08:46:56 -07:00
|
|
|
return s.dispatch_width;
|
2024-07-12 13:52:46 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const unsigned *
|
|
|
|
|
brw_compile_bs(const struct brw_compiler *compiler,
|
|
|
|
|
struct brw_compile_bs_params *params)
|
|
|
|
|
{
|
|
|
|
|
nir_shader *shader = params->base.nir;
|
|
|
|
|
struct brw_bs_prog_data *prog_data = params->prog_data;
|
|
|
|
|
unsigned num_resume_shaders = params->num_resume_shaders;
|
|
|
|
|
nir_shader **resume_shaders = params->resume_shaders;
|
2025-05-16 23:28:04 +00:00
|
|
|
const bool debug_enabled = brw_should_print_shader(shader, DEBUG_RT, params->base.source_hash);
|
2024-07-12 13:52:46 -07:00
|
|
|
|
2025-02-12 12:42:08 +02:00
|
|
|
brw_prog_data_init(&prog_data->base, ¶ms->base);
|
2024-07-12 13:52:46 -07:00
|
|
|
|
|
|
|
|
prog_data->max_stack_size = 0;
|
|
|
|
|
prog_data->num_resume_shaders = num_resume_shaders;
|
|
|
|
|
|
2024-12-06 16:33:35 -08:00
|
|
|
brw_generator g(compiler, ¶ms->base, &prog_data->base,
|
2024-07-12 13:52:46 -07:00
|
|
|
shader->info.stage);
|
|
|
|
|
if (unlikely(debug_enabled)) {
|
|
|
|
|
char *name = ralloc_asprintf(params->base.mem_ctx,
|
|
|
|
|
"%s %s shader %s",
|
|
|
|
|
shader->info.label ?
|
|
|
|
|
shader->info.label : "unnamed",
|
|
|
|
|
gl_shader_stage_name(shader->info.stage),
|
|
|
|
|
shader->info.name);
|
|
|
|
|
g.enable_debug(name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
prog_data->simd_size =
|
|
|
|
|
compile_single_bs(compiler, params, params->key, prog_data,
|
2025-01-29 11:05:49 -08:00
|
|
|
shader, &g, params->base.stats, NULL, NULL);
|
2024-07-12 13:52:46 -07:00
|
|
|
if (prog_data->simd_size == 0)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
uint64_t *resume_sbt = ralloc_array(params->base.mem_ctx,
|
|
|
|
|
uint64_t, num_resume_shaders);
|
|
|
|
|
for (unsigned i = 0; i < num_resume_shaders; i++) {
|
|
|
|
|
if (INTEL_DEBUG(DEBUG_RT)) {
|
|
|
|
|
char *name = ralloc_asprintf(params->base.mem_ctx,
|
|
|
|
|
"%s %s resume(%u) shader %s",
|
|
|
|
|
shader->info.label ?
|
|
|
|
|
shader->info.label : "unnamed",
|
|
|
|
|
gl_shader_stage_name(shader->info.stage),
|
|
|
|
|
i, shader->info.name);
|
|
|
|
|
g.enable_debug(name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* TODO: Figure out shader stats etc. for resume shaders */
|
|
|
|
|
int offset = 0;
|
|
|
|
|
uint8_t simd_size =
|
|
|
|
|
compile_single_bs(compiler, params, params->key,
|
2025-01-29 11:05:49 -08:00
|
|
|
prog_data, resume_shaders[i], &g, NULL, &offset,
|
|
|
|
|
&resume_sbt[i]);
|
2024-07-12 13:52:46 -07:00
|
|
|
if (simd_size == 0)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
assert(offset > 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* We only have one constant data so we want to make sure they're all the
|
|
|
|
|
* same.
|
|
|
|
|
*/
|
|
|
|
|
for (unsigned i = 0; i < num_resume_shaders; i++) {
|
|
|
|
|
assert(resume_shaders[i]->constant_data_size ==
|
|
|
|
|
shader->constant_data_size);
|
|
|
|
|
assert(memcmp(resume_shaders[i]->constant_data,
|
|
|
|
|
shader->constant_data,
|
|
|
|
|
shader->constant_data_size) == 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
g.add_const_data(shader->constant_data, shader->constant_data_size);
|
|
|
|
|
g.add_resume_sbt(num_resume_shaders, resume_sbt);
|
|
|
|
|
|
|
|
|
|
return g.get_assembly();
|
|
|
|
|
}
|