r600/sfn: Split r600_shader_from_nir into common and Gallium parts

Signed-off-by: Vitaliy Triang3l Kuzmin <triang3l@yandex.ru>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25695>
This commit is contained in:
Vitaliy Triang3l Kuzmin
2023-10-07 20:48:10 +03:00
committed by Marge Bot
parent c78aa6a417
commit 5419f52967
12 changed files with 281 additions and 145 deletions
+3
View File
@@ -1,2 +1,5 @@
[*.{c,h}]
indent_style = tab
[r600_sfn.{cpp,h}]
indent_style = space
+2
View File
@@ -45,6 +45,8 @@ files_r600 = files(
'r600_pipe.c',
'r600_pipe.h',
'r600_public.h',
'r600_sfn.cpp',
'r600_sfn.h',
'r600_shader.c',
'r600_shader.h',
'r600_shader_common.h',
+1 -3
View File
@@ -23,6 +23,7 @@
#include "r600_pipe.h"
#include "r600_public.h"
#include "r600_isa.h"
#include "r600_sfn.h"
#include "evergreen_compute.h"
#include "r600d.h"
@@ -663,9 +664,6 @@ static struct pipe_resource *r600_resource_create(struct pipe_screen *screen,
return r600_resource_create_common(screen, templ);
}
char *
r600_finalize_nir(struct pipe_screen *screen, void *shader);
struct pipe_screen *r600_screen_create(struct radeon_winsys *ws,
const struct pipe_screen_config *config)
{
+181
View File
@@ -0,0 +1,181 @@
/* -*- mesa-c++ -*-
*
* Copyright (c) 2019 Collabora LTD
*
* Author: Gert Wollny <gert.wollny@collabora.com>
*
* 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 "r600_sfn.h"
#include "compiler/nir/nir.h"
#include "compiler/shader_enums.h"
#include "sfn/sfn_assembler.h"
#include "sfn/sfn_debug.h"
#include "sfn/sfn_memorypool.h"
#include "sfn/sfn_nir.h"
#include "sfn/sfn_shader.h"
#include "r600_asm.h"
#include "r600_pipe.h"
#include "util/macros.h"
#include "util/ralloc.h"
#include <cassert>
#include <cstdio>
#include <cstring>
#include <iostream>
char *
r600_finalize_nir(pipe_screen *screen, void *shader)
{
auto rs = container_of(screen, r600_screen, b.b);
auto nir = static_cast<nir_shader *>(shader);
r600_finalize_nir_common(nir, rs->b.gfx_level);
return nullptr;
}
class MallocPoolRelease {
public:
MallocPoolRelease() { r600::init_pool(); }
~MallocPoolRelease() { r600::release_pool(); }
};
int
r600_shader_from_nir(struct r600_context *rctx,
struct r600_pipe_shader *pipeshader,
r600_shader_key *key)
{
MallocPoolRelease pool_release;
struct r600_pipe_shader_selector *sel = pipeshader->selector;
if (rctx->screen->b.debug_flags & DBG_PREOPT_IR) {
fprintf(stderr, "PRE-OPT-NIR-----------.------------------------------\n");
nir_print_shader(sel->nir, stderr);
fprintf(stderr, "END PRE-OPT-NIR--------------------------------------\n\n");
}
auto sh = nir_shader_clone(sel->nir, sel->nir);
r600_lower_and_optimize_nir(sh, key, rctx->b.gfx_level, &sel->so);
if (rctx->screen->b.debug_flags & DBG_ALL_SHADERS) {
fprintf(stderr,
"-- NIR --------------------------------------------------------\n");
struct nir_function *func =
(struct nir_function *)exec_list_get_head(&sh->functions);
nir_index_ssa_defs(func->impl);
nir_print_shader(sh, stderr);
fprintf(stderr,
"-- END --------------------------------------------------------\n");
}
memset(&pipeshader->shader, 0, sizeof(r600_shader));
pipeshader->scratch_space_needed = sh->scratch_size;
if (sh->info.stage == MESA_SHADER_TESS_EVAL || sh->info.stage == MESA_SHADER_VERTEX ||
sh->info.stage == MESA_SHADER_GEOMETRY) {
pipeshader->shader.clip_dist_write |=
((1 << sh->info.clip_distance_array_size) - 1);
pipeshader->shader.cull_dist_write = ((1 << sh->info.cull_distance_array_size) - 1)
<< sh->info.clip_distance_array_size;
pipeshader->shader.cc_dist_mask =
(1 << (sh->info.cull_distance_array_size + sh->info.clip_distance_array_size)) -
1;
}
struct r600_shader *gs_shader = nullptr;
if (rctx->gs_shader)
gs_shader = &rctx->gs_shader->current->shader;
r600_screen *rscreen = rctx->screen;
r600::Shader *shader =
r600::Shader::translate_from_nir(sh, &sel->so, gs_shader, *key,
rctx->isa->hw_class, rscreen->b.family);
assert(shader);
if (!shader)
return -2;
pipeshader->enabled_stream_buffers_mask = shader->enabled_stream_buffers_mask();
pipeshader->selector->info.file_count[TGSI_FILE_HW_ATOMIC] +=
shader->atomic_file_count();
pipeshader->selector->info.writes_memory =
shader->has_flag(r600::Shader::sh_writes_memory);
r600_finalize_and_optimize_shader(shader);
auto scheduled_shader = r600_schedule_shader(shader);
if (!scheduled_shader) {
return -1;
}
scheduled_shader->get_shader_info(&pipeshader->shader);
pipeshader->shader.uses_doubles = sh->info.bit_sizes_float & 64 ? 1 : 0;
r600_bytecode_init(&pipeshader->shader.bc,
rscreen->b.gfx_level,
rscreen->b.family,
rscreen->has_compressed_msaa_texturing);
/* We already schedule the code with this in mind, no need to handle this
* in the backend assembler */
pipeshader->shader.bc.ar_handling = AR_HANDLE_NORMAL;
pipeshader->shader.bc.r6xx_nop_after_rel_dst = 0;
r600::sfn_log << r600::SfnLog::shader_info << "pipeshader->shader.processor_type = "
<< pipeshader->shader.processor_type << "\n";
pipeshader->shader.bc.type = pipeshader->shader.processor_type;
pipeshader->shader.bc.isa = rctx->isa;
pipeshader->shader.bc.ngpr = scheduled_shader->required_registers();
r600::Assembler afs(&pipeshader->shader, *key);
if (!afs.lower(scheduled_shader)) {
R600_ERR("%s: Lowering to assembly failed\n", __func__);
scheduled_shader->print(std::cerr);
/* For now crash if the shader could not be generated */
assert(0);
return -1;
}
if (sh->info.stage == MESA_SHADER_VERTEX) {
pipeshader->shader.vs_position_window_space =
sh->info.vs.window_space_position;
}
if (sh->info.stage == MESA_SHADER_FRAGMENT)
pipeshader->shader.ps_conservative_z =
sh->info.fs.depth_layout;
if (sh->info.stage == MESA_SHADER_GEOMETRY) {
r600::sfn_log << r600::SfnLog::shader_info
<< "Geometry shader, create copy shader\n";
generate_gs_copy_shader(rctx, pipeshader, &sel->so);
assert(pipeshader->gs_copy_shader);
} else {
r600::sfn_log << r600::SfnLog::shader_info << "This is not a Geometry shader\n";
}
ralloc_free(sh);
return 0;
}
+50
View File
@@ -0,0 +1,50 @@
/* -*- mesa-c++ -*-
*
* Copyright (c) 2019 Collabora LTD
*
* Author: Gert Wollny <gert.wollny@collabora.com>
*
* 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.
*/
#ifndef R600_SFN_H
#define R600_SFN_H
#include "r600_pipe.h"
#include "r600_shader.h"
#include "pipe/p_screen.h"
#ifdef __cplusplus
extern "C" {
#endif
char *
r600_finalize_nir(struct pipe_screen *screen, void *shader);
int
r600_shader_from_nir(struct r600_context *rctx,
struct r600_pipe_shader *pipeshader,
union r600_shader_key *key);
#ifdef __cplusplus
}
#endif
#endif // R600_SFN_H
+1
View File
@@ -27,6 +27,7 @@
#include "r600_sq.h"
#include "r600_formats.h"
#include "r600_opcodes.h"
#include "r600_sfn.h"
#include "r600_shader.h"
#include "r600_dump.h"
#include "r600d.h"
+24 -132
View File
@@ -710,19 +710,9 @@ r600_lower_to_scalar_instr_filter(const nir_instr *instr, const void *)
}
}
class MallocPoolRelease {
public:
MallocPoolRelease() { r600::init_pool(); }
~MallocPoolRelease() { r600::release_pool(); }
};
extern "C" char *
r600_finalize_nir(pipe_screen *screen, void *shader)
void
r600_finalize_nir_common(nir_shader *nir, enum amd_gfx_level gfx_level)
{
r600_screen *rs = (r600_screen *)screen;
nir_shader *nir = (nir_shader *)shader;
const int nir_lower_flrp_mask = 16 | 32 | 64;
NIR_PASS_V(nir, nir_lower_flrp, nir_lower_flrp_mask, false);
@@ -730,7 +720,7 @@ r600_finalize_nir(pipe_screen *screen, void *shader)
nir_lower_idiv_options idiv_options = {0};
NIR_PASS_V(nir, nir_lower_idiv, &idiv_options);
NIR_PASS_V(nir, r600_nir_lower_trigen, rs->b.gfx_level);
NIR_PASS_V(nir, r600_nir_lower_trigen, gfx_level);
NIR_PASS_V(nir, nir_lower_phis_to_scalar, false);
NIR_PASS_V(nir, nir_lower_undef_to_zero);
@@ -749,38 +739,24 @@ r600_finalize_nir(pipe_screen *screen, void *shader)
NIR_PASS_V(nir, r600_lower_shared_io);
NIR_PASS_V(nir, r600_nir_lower_atomics);
if (rs->b.gfx_level == CAYMAN)
if (gfx_level == CAYMAN)
NIR_PASS_V(nir, r600_legalize_image_load_store);
while (optimize_once(nir))
;
return NULL;
}
int
r600_shader_from_nir(struct r600_context *rctx,
struct r600_pipe_shader *pipeshader,
r600_shader_key *key)
void
r600_lower_and_optimize_nir(nir_shader *sh,
const union r600_shader_key *key,
enum amd_gfx_level gfx_level,
struct pipe_stream_output_info *so_info)
{
MallocPoolRelease pool_release;
struct r600_pipe_shader_selector *sel = pipeshader->selector;
bool lower_64bit =
(rctx->b.gfx_level < CAYMAN &&
(sel->nir->options->lower_int64_options ||
sel->nir->options->lower_doubles_options) &&
(sel->nir->info.bit_sizes_float | sel->nir->info.bit_sizes_int) & 64);
gfx_level < CAYMAN &&
(sh->options->lower_int64_options || sh->options->lower_doubles_options) &&
((sh->info.bit_sizes_float | sh->info.bit_sizes_int) & 64);
if (rctx->screen->b.debug_flags & DBG_PREOPT_IR) {
fprintf(stderr, "PRE-OPT-NIR-----------.------------------------------\n");
nir_print_shader(sel->nir, stderr);
fprintf(stderr, "END PRE-OPT-NIR--------------------------------------\n\n");
}
auto sh = nir_shader_clone(sel->nir, sel->nir);
r600::sort_uniforms(sh);
while (optimize_once(sh))
@@ -829,7 +805,7 @@ r600_shader_from_nir(struct r600_context *rctx,
if (r600_is_last_vertex_stage(sh, *key))
r600_lower_clipvertex_to_clipdist(sh, sel->so);
r600_lower_clipvertex_to_clipdist(sh, *so_info);
if (sh->info.stage == MESA_SHADER_TESS_CTRL ||
sh->info.stage == MESA_SHADER_TESS_EVAL ||
@@ -852,7 +828,7 @@ r600_shader_from_nir(struct r600_context *rctx,
NIR_PASS_V(sh, nir_lower_phis_to_scalar, false);
NIR_PASS_V(sh, nir_lower_alu_to_scalar, r600_lower_to_scalar_instr_filter, NULL);
NIR_PASS_V(sh, r600_nir_lower_int_tg4);
NIR_PASS_V(sh, r600::r600_nir_lower_tex_to_backend, rctx->b.gfx_level);
NIR_PASS_V(sh, r600::r600_nir_lower_tex_to_backend, gfx_level);
if ((sh->info.bit_sizes_float | sh->info.bit_sizes_int) & 64) {
NIR_PASS_V(sh, r600::r600_nir_split_64bit_io);
@@ -907,50 +883,11 @@ r600_shader_from_nir(struct r600_context *rctx,
NIR_PASS_V(sh, nir_lower_locals_to_regs, 32);
NIR_PASS_V(sh, nir_convert_from_ssa, true);
NIR_PASS_V(sh, nir_opt_dce);
}
if (rctx->screen->b.debug_flags & DBG_ALL_SHADERS) {
fprintf(stderr,
"-- NIR --------------------------------------------------------\n");
struct nir_function *func =
(struct nir_function *)exec_list_get_head(&sh->functions);
nir_index_ssa_defs(func->impl);
nir_print_shader(sh, stderr);
fprintf(stderr,
"-- END --------------------------------------------------------\n");
}
memset(&pipeshader->shader, 0, sizeof(r600_shader));
pipeshader->scratch_space_needed = sh->scratch_size;
if (sh->info.stage == MESA_SHADER_TESS_EVAL || sh->info.stage == MESA_SHADER_VERTEX ||
sh->info.stage == MESA_SHADER_GEOMETRY) {
pipeshader->shader.clip_dist_write |=
((1 << sh->info.clip_distance_array_size) - 1);
pipeshader->shader.cull_dist_write = ((1 << sh->info.cull_distance_array_size) - 1)
<< sh->info.clip_distance_array_size;
pipeshader->shader.cc_dist_mask =
(1 << (sh->info.cull_distance_array_size + sh->info.clip_distance_array_size)) -
1;
}
struct r600_shader *gs_shader = nullptr;
if (rctx->gs_shader)
gs_shader = &rctx->gs_shader->current->shader;
r600_screen *rscreen = rctx->screen;
r600::Shader *shader =
r600::Shader::translate_from_nir(sh, &sel->so, gs_shader, *key,
rctx->isa->hw_class, rscreen->b.family);
assert(shader);
if (!shader)
return -2;
pipeshader->enabled_stream_buffers_mask = shader->enabled_stream_buffers_mask();
pipeshader->selector->info.file_count[TGSI_FILE_HW_ATOMIC] +=
shader->atomic_file_count();
pipeshader->selector->info.writes_memory =
shader->has_flag(r600::Shader::sh_writes_memory);
void
r600_finalize_and_optimize_shader(r600::Shader *shader)
{
if (r600::sfn_log.has_debug_flag(r600::SfnLog::steps)) {
std::cerr << "Shader after conversion from nir\n";
shader->print(std::cerr);
@@ -980,7 +917,11 @@ r600_shader_from_nir(struct r600_context *rctx,
shader->print(std::cerr);
}
}
}
r600::Shader *
r600_schedule_shader(r600::Shader *shader)
{
auto scheduled_shader = r600::schedule(shader);
if (r600::sfn_log.has_debug_flag(r600::SfnLog::steps)) {
std::cerr << "Shader after scheduling\n";
@@ -1001,7 +942,7 @@ r600_shader_from_nir(struct r600_context *rctx,
R600_ERR("%s: Register allocation failed\n", __func__);
/* For now crash if the shader could not be benerated */
assert(0);
return -1;
return nullptr;
} else if (r600::sfn_log.has_debug_flag(r600::SfnLog::merge) ||
r600::sfn_log.has_debug_flag(r600::SfnLog::steps)) {
r600::sfn_log << "Shader after RA\n";
@@ -1009,54 +950,5 @@ r600_shader_from_nir(struct r600_context *rctx,
}
}
scheduled_shader->get_shader_info(&pipeshader->shader);
pipeshader->shader.uses_doubles = sh->info.bit_sizes_float & 64 ? 1 : 0;
r600_bytecode_init(&pipeshader->shader.bc,
rscreen->b.gfx_level,
rscreen->b.family,
rscreen->has_compressed_msaa_texturing);
/* We already schedule the code with this in mind, no need to handle this
* in the backend assembler */
pipeshader->shader.bc.ar_handling = AR_HANDLE_NORMAL;
pipeshader->shader.bc.r6xx_nop_after_rel_dst = 0;
r600::sfn_log << r600::SfnLog::shader_info << "pipeshader->shader.processor_type = "
<< pipeshader->shader.processor_type << "\n";
pipeshader->shader.bc.type = pipeshader->shader.processor_type;
pipeshader->shader.bc.isa = rctx->isa;
pipeshader->shader.bc.ngpr = scheduled_shader->required_registers();
r600::Assembler afs(&pipeshader->shader, *key);
if (!afs.lower(scheduled_shader)) {
R600_ERR("%s: Lowering to assembly failed\n", __func__);
scheduled_shader->print(std::cerr);
/* For now crash if the shader could not be generated */
assert(0);
return -1;
}
if (sh->info.stage == MESA_SHADER_VERTEX) {
pipeshader->shader.vs_position_window_space =
sh->info.vs.window_space_position;
}
if (sh->info.stage == MESA_SHADER_FRAGMENT)
pipeshader->shader.ps_conservative_z =
sh->info.fs.depth_layout;
if (sh->info.stage == MESA_SHADER_GEOMETRY) {
r600::sfn_log << r600::SfnLog::shader_info
<< "Geometry shader, create copy shader\n";
generate_gs_copy_shader(rctx, pipeshader, &sel->so);
assert(pipeshader->gs_copy_shader);
} else {
r600::sfn_log << r600::SfnLog::shader_info << "This is not a Geometry shader\n";
}
ralloc_free(sh);
return 0;
return scheduled_shader;
}
+15 -6
View File
@@ -27,6 +27,9 @@
#ifndef SFN_NIR_H
#define SFN_NIR_H
#include "gallium/include/pipe/p_state.h"
#include "amd_family.h"
#include "nir.h"
#include "nir_builder.h"
@@ -111,6 +114,11 @@ r600_append_tcs_TF_emission(nir_shader *shader, enum mesa_prim prim_type);
bool
r600_legalize_image_load_store(nir_shader *shader);
void
r600_finalize_and_optimize_shader(r600::Shader *shader);
r600::Shader *
r600_schedule_shader(r600::Shader *shader);
#else
#include "gallium/drivers/r600/r600_shader.h"
#endif
@@ -125,13 +133,14 @@ r600_vectorize_vs_inputs(nir_shader *shader);
bool
r600_lower_to_scalar_instr_filter(const nir_instr *instr, const void *);
int
r600_shader_from_nir(struct r600_context *rctx,
struct r600_pipe_shader *pipeshader,
union r600_shader_key *key);
void
r600_lower_and_optimize_nir(nir_shader *sh,
const union r600_shader_key *key,
enum amd_gfx_level gfx_level,
struct pipe_stream_output_info *so_info);
char *
r600_finalize_nir(struct pipe_screen *screen, void *shader);
void
r600_finalize_nir_common(nir_shader *nir, enum amd_gfx_level gfx_level);
#ifdef __cplusplus
}
+1 -1
View File
@@ -477,7 +477,7 @@ Shader *
Shader::translate_from_nir(nir_shader *nir,
const pipe_stream_output_info *so_info,
struct r600_shader *gs_shader,
r600_shader_key& key,
const r600_shader_key& key,
r600_chip_class chip_class,
radeon_family family)
{
+1 -1
View File
@@ -144,7 +144,7 @@ public:
static Shader *translate_from_nir(nir_shader *nir,
const pipe_stream_output_info *so_info,
r600_shader *gs_shader,
r600_shader_key& key,
const r600_shader_key& key,
r600_chip_class chip_class,
radeon_family family);
@@ -414,7 +414,7 @@ VertexExportForFs::output_register(int loc) const
VertexShader::VertexShader(const pipe_stream_output_info *so_info,
r600_shader *gs_shader,
r600_shader_key& key):
const r600_shader_key& key):
VertexStageShader("VS", key.vs.first_atomic_counter),
m_vs_as_gs_a(key.vs.as_gs_a)
{
+1 -1
View File
@@ -159,7 +159,7 @@ class VertexShader : public VertexStageShader {
public:
VertexShader(const pipe_stream_output_info *so_info,
r600_shader *gs_shader,
r600_shader_key& key);
const r600_shader_key& key);
bool load_input(nir_intrinsic_instr *intr) override;
bool store_output(nir_intrinsic_instr *intr) override;