asahi: Stub command-line compiler for AGX G13B

Based on the Bifrost standalone compiler, which was based on Midgard's
standalone compiler, which was based on Freedreno's standalone compiler,
which was.....

It's like sour dough!

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Acked-by: Jason Ekstrand <jason@jlekstrand.net>
Acked-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10582>
This commit is contained in:
Alyssa Rosenzweig 2021-04-10 20:17:21 -04:00 committed by Alyssa Rosenzweig
parent 0ea67e57e5
commit 972409dacb
8 changed files with 447 additions and 1 deletions

View File

@ -71,6 +71,7 @@ if with_tools.contains('all')
'nir',
'nouveau',
'xvmc',
'asahi',
]
endif
with_clc = false

View File

@ -398,7 +398,7 @@ option(
'tools',
type : 'array',
value : [],
choices : ['drm-shim', 'etnaviv', 'freedreno', 'glsl', 'intel', 'intel-ui', 'nir', 'nouveau', 'xvmc', 'lima', 'panfrost', 'all'],
choices : ['drm-shim', 'etnaviv', 'freedreno', 'glsl', 'intel', 'intel-ui', 'nir', 'nouveau', 'xvmc', 'lima', 'panfrost', 'asahi', 'all'],
description : 'List of tools to build. (Note: `intel-ui` selects `intel`)',
)
option(

View File

View File

@ -0,0 +1,165 @@
/*
* Copyright (C) 2018-2021 Alyssa Rosenzweig <alyssa@rosenzweig.io>
*
* 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
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* 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 NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS 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 __AGX_PUBLIC_H_
#define __AGX_PUBLIC_H_
#include "compiler/nir/nir.h"
#include "util/u_dynarray.h"
enum agx_push_type {
/* Array of 64-bit pointers to the base addresses (BASES) and array of
* 16-bit sizes for optional bounds checking (SIZES) */
AGX_PUSH_UBO_BASES = 0,
AGX_PUSH_UBO_SIZES = 1,
AGX_PUSH_VBO_BASES = 2,
AGX_PUSH_VBO_SIZES = 3,
AGX_PUSH_SSBO_BASES = 4,
AGX_PUSH_SSBO_SIZES = 5,
/* Push the attached constant memory */
AGX_PUSH_CONSTANTS = 6,
/* Push the content of a UBO */
AGX_PUSH_UBO_DATA = 7,
/* Keep last */
AGX_PUSH_NUM_TYPES
};
struct agx_push {
/* Contents to push */
enum agx_push_type type : 8;
/* Base of where to push, indexed in 16-bit units. The uniform file contains
* 512 = 2^9 such units. */
unsigned base : 9;
/* Number of 16-bit units to push */
unsigned length : 9;
/* If set, rather than pushing the specified data, push a pointer to the
* specified data. This is slower to access but enables indirect access, as
* the uniform file does not support indirection. */
bool indirect : 1;
union {
struct {
uint16_t ubo;
uint16_t offset;
} ubo_data;
};
};
/* Arbitrary */
#define AGX_MAX_PUSH_RANGES (16)
struct agx_shader_info {
unsigned push_ranges;
struct agx_push push[AGX_MAX_PUSH_RANGES];
};
#define AGX_MAX_RTS (8)
#define AGX_MAX_ATTRIBS (16)
#define AGX_MAX_VBUFS (16)
enum agx_format {
AGX_FORMAT_I8 = 0,
AGX_FORMAT_I16 = 1,
AGX_FORMAT_I32 = 2,
AGX_FORMAT_F16 = 3,
AGX_FORMAT_U8NORM = 4,
AGX_FORMAT_S8NORM = 5,
AGX_FORMAT_U16NORM = 6,
AGX_FORMAT_S16NORM = 7,
AGX_FORMAT_RGB10A2 = 8,
AGX_FORMAT_SRGBA8 = 10,
AGX_FORMAT_RG11B10F = 12,
AGX_FORMAT_RGB9E5 = 13,
};
struct agx_attribute {
unsigned buf : 5;
unsigned src_offset : 16;
unsigned nr_comps_minus_1 : 2;
enum agx_format format : 4;
};
struct agx_vs_shader_key {
unsigned num_vbufs;
unsigned vbuf_strides[AGX_MAX_VBUFS];
struct agx_attribute attributes[AGX_MAX_ATTRIBS];
};
struct agx_fs_shader_key {
enum agx_format tib_formats[AGX_MAX_RTS];
};
struct agx_shader_key {
union {
struct agx_vs_shader_key vs;
struct agx_fs_shader_key fs;
};
};
void
agx_compile_shader_nir(nir_shader *nir,
struct agx_shader_key *key,
struct util_dynarray *binary,
struct agx_shader_info *out);
static const nir_shader_compiler_options agx_nir_options = {
.lower_scmp = true,
.lower_flrp16 = true,
.lower_flrp32 = true,
.lower_ffract = true,
.lower_fmod = true,
.lower_fdiv = true,
.lower_isign = true,
.lower_iabs = true,
.lower_fpow = true,
.lower_find_lsb = true,
.lower_ifind_msb = true,
.lower_fdph = true,
.lower_wpos_pntc = true,
.lower_fsign = true,
.lower_rotate = true,
.lower_pack_split = true,
.lower_uniforms_to_ubo = true,
.lower_cs_local_index_from_id = true,
.lower_doubles_options = nir_lower_dmod,
.lower_int64_options = ~(nir_lower_iadd64 | nir_lower_imul_2x32_64),
.has_fsub = true,
.has_isub = true,
.has_cs_global_id = true,
.vectorize_io = true,
.fuse_ffma16 = true,
.fuse_ffma32 = true,
.use_interpolated_input_intrinsics = true,
};
#endif

View File

@ -0,0 +1,194 @@
/*
* Copyright (C) 2019 Ryan Houdek <Sonicadvance1@gmail.com>
* Copyright (C) 2014 Rob Clark <robclark@freedesktop.org>
* Copyright © 2015 Red Hat
*
* 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
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* 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 NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS 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 "main/mtypes.h"
#include "compiler/glsl/standalone.h"
#include "compiler/glsl/glsl_to_nir.h"
#include "compiler/glsl/gl_nir.h"
#include "compiler/nir_types.h"
#include "util/u_dynarray.h"
#include "agx_compile.h"
static int
st_packed_uniforms_type_size(const struct glsl_type *type, bool bindless)
{
return glsl_count_dword_slots(type, bindless);
}
static int
glsl_type_size(const struct glsl_type *type, bool bindless)
{
return glsl_count_attribute_slots(type, false);
}
static void
insert_sorted(struct exec_list *var_list, nir_variable *new_var)
{
nir_foreach_variable_in_list (var, var_list) {
if (var->data.location > new_var->data.location) {
exec_node_insert_node_before(&var->node, &new_var->node);
return;
}
}
exec_list_push_tail(var_list, &new_var->node);
}
static void
sort_varyings(nir_shader *nir, nir_variable_mode mode)
{
struct exec_list new_list;
exec_list_make_empty(&new_list);
nir_foreach_variable_with_modes_safe (var, nir, mode) {
exec_node_remove(&var->node);
insert_sorted(&new_list, var);
}
exec_list_append(&nir->variables, &new_list);
}
static void
fixup_varying_slots(nir_shader *nir, nir_variable_mode mode)
{
nir_foreach_variable_with_modes (var, nir, mode) {
if (var->data.location >= VARYING_SLOT_VAR0) {
var->data.location += 9;
} else if ((var->data.location >= VARYING_SLOT_TEX0) &&
(var->data.location <= VARYING_SLOT_TEX7)) {
var->data.location += VARYING_SLOT_VAR0 - VARYING_SLOT_TEX0;
}
}
}
static void
compile_shader(char **argv)
{
struct gl_shader_program *prog;
nir_shader *nir[2];
unsigned shader_types[2] = {
MESA_SHADER_VERTEX,
MESA_SHADER_FRAGMENT,
};
struct standalone_options options = {
.glsl_version = 310, /* ES - needed for precision */
.do_link = true,
.lower_precision = true
};
static struct gl_context local_ctx;
prog = standalone_compile_shader(&options, 2, argv, &local_ctx);
prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program->info.stage = MESA_SHADER_FRAGMENT;
struct util_dynarray binary;
util_dynarray_init(&binary, NULL);
for (unsigned i = 0; i < 2; ++i) {
nir[i] = glsl_to_nir(&local_ctx, prog, shader_types[i], &agx_nir_options);
if (i == 0) {
nir_assign_var_locations(nir[i], nir_var_shader_in, &nir[i]->num_inputs,
glsl_type_size);
sort_varyings(nir[i], nir_var_shader_out);
nir_assign_var_locations(nir[i], nir_var_shader_out, &nir[i]->num_outputs,
glsl_type_size);
fixup_varying_slots(nir[i], nir_var_shader_out);
} else {
sort_varyings(nir[i], nir_var_shader_in);
nir_assign_var_locations(nir[i], nir_var_shader_in, &nir[i]->num_inputs,
glsl_type_size);
fixup_varying_slots(nir[i], nir_var_shader_in);
nir_assign_var_locations(nir[i], nir_var_shader_out, &nir[i]->num_outputs,
glsl_type_size);
}
nir_assign_var_locations(nir[i], nir_var_uniform, &nir[i]->num_uniforms,
glsl_type_size);
NIR_PASS_V(nir[i], nir_lower_global_vars_to_local);
NIR_PASS_V(nir[i], nir_lower_io_to_temporaries, nir_shader_get_entrypoint(nir[i]), true, i == 0);
NIR_PASS_V(nir[i], nir_lower_system_values);
NIR_PASS_V(nir[i], gl_nir_lower_samplers, prog);
NIR_PASS_V(nir[i], nir_split_var_copies);
NIR_PASS_V(nir[i], nir_lower_var_copies);
NIR_PASS_V(nir[i], nir_lower_io, nir_var_uniform,
st_packed_uniforms_type_size,
(nir_lower_io_options)0);
NIR_PASS_V(nir[i], nir_lower_uniforms_to_ubo, true, false);
/* before buffers and vars_to_ssa */
NIR_PASS_V(nir[i], gl_nir_lower_images, true);
NIR_PASS_V(nir[i], gl_nir_lower_buffers, prog);
NIR_PASS_V(nir[i], nir_opt_constant_folding);
util_dynarray_clear(&binary);
}
util_dynarray_fini(&binary);
}
static void
disassemble(const char *filename, bool verbose)
{
FILE *fp = fopen(filename, "rb");
assert(fp);
fseek(fp, 0, SEEK_END);
unsigned filesize = ftell(fp);
rewind(fp);
uint32_t *code = malloc(filesize);
unsigned res = fread(code, 1, filesize, fp);
if (res != filesize) {
printf("Couldn't read full file\n");
}
fclose(fp);
/* TODO: stub */
free(code);
}
int
main(int argc, char **argv)
{
if (argc < 2) {
printf("Pass a command\n");
exit(1);
}
if (strcmp(argv[1], "compile") == 0)
compile_shader(&argv[2]);
else if (strcmp(argv[1], "disasm") == 0)
disassemble(argv[2], false);
else if (strcmp(argv[1], "disasm-verbose") == 0)
disassemble(argv[2], true);
else
unreachable("Unknown command. Valid: compile/disasm/disasm-verbose");
return 0;
}

View File

@ -0,0 +1,34 @@
# Copyright © 2018 Rob Clark
# Copyright © 2019 Collabora
# 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 the rights
# to use, copy, modify, merge, publish, distribute, sublicense, 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 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 NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS 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.
libasahi_agx_files = files(
'agx_compile.c',
)
libasahi_compiler = static_library(
'asahi_compiler',
[libasahi_agx_files],
include_directories : [inc_include, inc_src, inc_mesa, inc_gallium, inc_gallium_aux, inc_mapi],
dependencies: [idep_nir],
c_args : [no_override_init_args],
gnu_symbol_visibility : 'hidden',
build_by_default : false,
)

49
src/asahi/meson.build Normal file
View File

@ -0,0 +1,49 @@
# Copyright © 2018 Rob Clark
# Copyright © 2019 Collabora
# 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 the rights
# to use, copy, modify, merge, publish, distribute, sublicense, 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 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 NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS 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.
subdir('compiler')
files_agx = files(
'compiler/cmdline.c',
)
agx_compiler = executable(
'agx_compiler',
[files_agx],
include_directories : [
inc_include,
inc_src,
inc_gallium,
inc_gallium_aux,
inc_mapi,
inc_mesa,
],
dependencies : [
idep_nir,
idep_mesautil,
dep_libdrm,
],
link_with : [
libglsl_standalone,
libasahi_compiler,
],
build_by_default : with_tools.contains('asahi')
)

View File

@ -98,6 +98,9 @@ endif
if with_gallium_nouveau
subdir('nouveau')
endif
if with_tools.contains('asahi')
subdir('asahi')
endif
subdir('mesa')
subdir('loader')
if with_platform_haiku