From c57bc5b9e8b05166137f07d69e191ac64ddea22c Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Thu, 31 Jan 2019 15:40:55 +0000 Subject: [PATCH] add kmsro build option, add work around for missing files in 'make dist' (fixed upstream) --- freedreno-meson.build | 24 ++ ir3_cmdline.c | 497 ++++++++++++++++++++++++++++++++++++++++++ mesa.spec | 12 +- 3 files changed, 532 insertions(+), 1 deletion(-) create mode 100644 freedreno-meson.build create mode 100644 ir3_cmdline.c diff --git a/freedreno-meson.build b/freedreno-meson.build new file mode 100644 index 0000000..a3db4b1 --- /dev/null +++ b/freedreno-meson.build @@ -0,0 +1,24 @@ +# Copyright © 2018 Rob Clark + +# 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. + +inc_freedreno = include_directories(['.', './registers']) + +subdir('drm') +subdir('ir3') diff --git a/ir3_cmdline.c b/ir3_cmdline.c new file mode 100644 index 0000000..364e62b --- /dev/null +++ b/ir3_cmdline.c @@ -0,0 +1,497 @@ +/* + * Copyright (C) 2014 Rob Clark + * + * 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. + * + * Authors: + * Rob Clark + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tgsi/tgsi_parse.h" +#include "tgsi/tgsi_text.h" +#include "tgsi/tgsi_dump.h" + +#include "ir3/ir3_compiler.h" +#include "ir3/ir3_gallium.h" +#include "ir3/ir3_nir.h" +#include "ir3/instr-a3xx.h" +#include "ir3/ir3.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 "compiler/spirv/nir_spirv.h" + +static void dump_info(struct ir3_shader_variant *so, const char *str) +{ + uint32_t *bin; + const char *type = ir3_shader_stage(so->shader); + bin = ir3_shader_assemble(so, so->shader->compiler->gpu_id); + debug_printf("; %s: %s\n", type, str); + ir3_shader_disasm(so, bin, stdout); + free(bin); +} + +static void +insert_sorted(struct exec_list *var_list, nir_variable *new_var) +{ + nir_foreach_variable(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(struct exec_list *var_list) +{ + struct exec_list new_list; + exec_list_make_empty(&new_list); + nir_foreach_variable_safe(var, var_list) { + exec_node_remove(&var->node); + insert_sorted(&new_list, var); + } + exec_list_move_nodes_to(&new_list, var_list); +} + +static void +fixup_varying_slots(struct exec_list *var_list) +{ + nir_foreach_variable(var, var_list) { + 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 struct ir3_compiler *compiler; + +static nir_shader * +load_glsl(unsigned num_files, char* const* files, gl_shader_stage stage) +{ + static const struct standalone_options options = { + .glsl_version = 460, + .do_link = true, + }; + struct gl_shader_program *prog; + const nir_shader_compiler_options *nir_options = + ir3_get_compiler_options(compiler); + + prog = standalone_compile_shader(&options, num_files, files); + if (!prog) + errx(1, "couldn't parse `%s'", files[0]); + + nir_shader *nir = glsl_to_nir(prog, stage, nir_options); + + /* required NIR passes: */ + if (nir_options->lower_all_io_to_temps || + nir->info.stage == MESA_SHADER_VERTEX || + nir->info.stage == MESA_SHADER_GEOMETRY) { + NIR_PASS_V(nir, nir_lower_io_to_temporaries, + nir_shader_get_entrypoint(nir), + true, true); + } else if (nir->info.stage == MESA_SHADER_FRAGMENT) { + NIR_PASS_V(nir, nir_lower_io_to_temporaries, + nir_shader_get_entrypoint(nir), + true, false); + } + + NIR_PASS_V(nir, nir_lower_global_vars_to_local); + NIR_PASS_V(nir, nir_split_var_copies); + NIR_PASS_V(nir, nir_lower_var_copies); + + NIR_PASS_V(nir, nir_split_var_copies); + NIR_PASS_V(nir, nir_lower_var_copies); + nir_print_shader(nir, stdout); + NIR_PASS_V(nir, gl_nir_lower_atomics, prog, true); + NIR_PASS_V(nir, nir_lower_atomics_to_ssbo, 8); + nir_print_shader(nir, stdout); + + switch (stage) { + case MESA_SHADER_VERTEX: + nir_assign_var_locations(&nir->inputs, + &nir->num_inputs, + ir3_glsl_type_size); + + /* Re-lower global vars, to deal with any dead VS inputs. */ + NIR_PASS_V(nir, nir_lower_global_vars_to_local); + + sort_varyings(&nir->outputs); + nir_assign_var_locations(&nir->outputs, + &nir->num_outputs, + ir3_glsl_type_size); + fixup_varying_slots(&nir->outputs); + break; + case MESA_SHADER_FRAGMENT: + sort_varyings(&nir->inputs); + nir_assign_var_locations(&nir->inputs, + &nir->num_inputs, + ir3_glsl_type_size); + fixup_varying_slots(&nir->inputs); + nir_assign_var_locations(&nir->outputs, + &nir->num_outputs, + ir3_glsl_type_size); + break; + case MESA_SHADER_COMPUTE: + case MESA_SHADER_KERNEL: + break; + default: + errx(1, "unhandled shader stage: %d", stage); + } + + nir_assign_var_locations(&nir->uniforms, + &nir->num_uniforms, + ir3_glsl_type_size); + + NIR_PASS_V(nir, nir_lower_system_values); + NIR_PASS_V(nir, nir_lower_io, nir_var_all, ir3_glsl_type_size, 0); + NIR_PASS_V(nir, gl_nir_lower_samplers, prog); + + return nir; +} + +static int +read_file(const char *filename, void **ptr, size_t *size) +{ + int fd, ret; + struct stat st; + + *ptr = MAP_FAILED; + + fd = open(filename, O_RDONLY); + if (fd == -1) { + warnx("couldn't open `%s'", filename); + return 1; + } + + ret = fstat(fd, &st); + if (ret) + errx(1, "couldn't stat `%s'", filename); + + *size = st.st_size; + *ptr = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); + if (*ptr == MAP_FAILED) + errx(1, "couldn't map `%s'", filename); + + close(fd); + + return 0; +} + +static void debug_func(void *priv, enum nir_spirv_debug_level level, + size_t spirv_offset, const char *message) +{ +// printf("%s\n", message); +} + +static nir_shader * +load_spirv(const char *filename, const char *entry, gl_shader_stage stage) +{ + const struct spirv_to_nir_options spirv_options = { + /* these caps are just make-believe */ + .caps = { + .draw_parameters = true, + .float64 = true, + .image_read_without_format = true, + .image_write_without_format = true, + .int64 = true, + .variable_pointers = true, + }, + .lower_workgroup_access_to_offsets = true, + .lower_ubo_ssbo_access_to_offsets = true, + .debug = { + .func = debug_func, + } + }; + nir_function *entry_point; + void *buf; + size_t size; + + read_file(filename, &buf, &size); + + entry_point = spirv_to_nir(buf, size / 4, + NULL, 0, /* spec_entries */ + stage, entry, + &spirv_options, + ir3_get_compiler_options(compiler)); + + nir_print_shader(entry_point->shader, stdout); + + return entry_point->shader; +} + +static void print_usage(void) +{ + printf("Usage: ir3_compiler [OPTIONS]... \n"); + printf(" --verbose - verbose compiler/debug messages\n"); + printf(" --binning-pass - generate binning pass shader (VERT)\n"); + printf(" --color-two-side - emulate two-sided color (FRAG)\n"); + printf(" --half-precision - use half-precision\n"); + printf(" --saturate-s MASK - bitmask of samplers to saturate S coord\n"); + printf(" --saturate-t MASK - bitmask of samplers to saturate T coord\n"); + printf(" --saturate-r MASK - bitmask of samplers to saturate R coord\n"); + printf(" --astc-srgb MASK - bitmask of samplers to enable astc-srgb workaround\n"); + printf(" --stream-out - enable stream-out (aka transform feedback)\n"); + printf(" --ucp MASK - bitmask of enabled user-clip-planes\n"); + printf(" --gpu GPU_ID - specify gpu-id (default 320)\n"); + printf(" --help - show this message\n"); +} + +int main(int argc, char **argv) +{ + int ret = 0, n = 1; + char *filenames[2]; + int num_files = 0; + unsigned stage = 0; + struct ir3_shader_variant v; + struct ir3_shader s; + struct ir3_shader_key key = {}; + /* TODO cmdline option to target different gpus: */ + unsigned gpu_id = 320; + const char *info; + const char *entry; + void *ptr; + bool from_spirv = false; + size_t size; + + memset(&s, 0, sizeof(s)); + memset(&v, 0, sizeof(v)); + + /* cmdline args which impact shader variant get spit out in a + * comment on the first line.. a quick/dirty way to preserve + * that info so when ir3test recompiles the shader with a new + * compiler version, we use the same shader-key settings: + */ + debug_printf("; options:"); + + while (n < argc) { + if (!strcmp(argv[n], "--verbose")) { + ir3_shader_debug |= IR3_DBG_OPTMSGS | IR3_DBG_DISASM; + n++; + continue; + } + + if (!strcmp(argv[n], "--binning-pass")) { + debug_printf(" %s", argv[n]); + v.binning_pass = true; + n++; + continue; + } + + if (!strcmp(argv[n], "--color-two-side")) { + debug_printf(" %s", argv[n]); + key.color_two_side = true; + n++; + continue; + } + + if (!strcmp(argv[n], "--half-precision")) { + debug_printf(" %s", argv[n]); + key.half_precision = true; + n++; + continue; + } + + if (!strcmp(argv[n], "--saturate-s")) { + debug_printf(" %s %s", argv[n], argv[n+1]); + key.vsaturate_s = key.fsaturate_s = strtol(argv[n+1], NULL, 0); + n += 2; + continue; + } + + if (!strcmp(argv[n], "--saturate-t")) { + debug_printf(" %s %s", argv[n], argv[n+1]); + key.vsaturate_t = key.fsaturate_t = strtol(argv[n+1], NULL, 0); + n += 2; + continue; + } + + if (!strcmp(argv[n], "--saturate-r")) { + debug_printf(" %s %s", argv[n], argv[n+1]); + key.vsaturate_r = key.fsaturate_r = strtol(argv[n+1], NULL, 0); + n += 2; + continue; + } + + if (!strcmp(argv[n], "--astc-srgb")) { + debug_printf(" %s %s", argv[n], argv[n+1]); + key.vastc_srgb = key.fastc_srgb = strtol(argv[n+1], NULL, 0); + n += 2; + continue; + } + + if (!strcmp(argv[n], "--stream-out")) { + struct ir3_stream_output_info *so = &s.stream_output; + debug_printf(" %s", argv[n]); + /* TODO more dynamic config based on number of outputs, etc + * rather than just hard-code for first output: + */ + so->num_outputs = 1; + so->stride[0] = 4; + so->output[0].register_index = 0; + so->output[0].start_component = 0; + so->output[0].num_components = 4; + so->output[0].output_buffer = 0; + so->output[0].dst_offset = 2; + so->output[0].stream = 0; + n++; + continue; + } + + if (!strcmp(argv[n], "--ucp")) { + debug_printf(" %s %s", argv[n], argv[n+1]); + key.ucp_enables = strtol(argv[n+1], NULL, 0); + n += 2; + continue; + } + + if (!strcmp(argv[n], "--gpu")) { + debug_printf(" %s %s", argv[n], argv[n+1]); + gpu_id = strtol(argv[n+1], NULL, 0); + n += 2; + continue; + } + + if (!strcmp(argv[n], "--help")) { + print_usage(); + return 0; + } + + break; + } + debug_printf("\n"); + + while (n < argc) { + char *filename = argv[n]; + char *ext = strrchr(filename, '.'); + + if (strcmp(ext, ".tgsi") == 0) { + if (num_files != 0) + errx(1, "in TGSI mode, only a single file may be specified"); + s.from_tgsi = true; + } else if (strcmp(ext, ".spv") == 0) { + if (num_files != 0) + errx(1, "in SPIR-V mode, only a single file may be specified"); + stage = MESA_SHADER_COMPUTE; + from_spirv = true; + filenames[num_files++] = filename; + n++; + if (n == argc) + errx(1, "in SPIR-V mode, an entry point must be specified"); + entry = argv[n]; + n++; + } else if (strcmp(ext, ".comp") == 0) { + if (s.from_tgsi || from_spirv) + errx(1, "cannot mix GLSL/TGSI/SPIRV"); + if (num_files >= ARRAY_SIZE(filenames)) + errx(1, "too many GLSL files"); + stage = MESA_SHADER_COMPUTE; + } else if (strcmp(ext, ".frag") == 0) { + if (s.from_tgsi || from_spirv) + errx(1, "cannot mix GLSL/TGSI/SPIRV"); + if (num_files >= ARRAY_SIZE(filenames)) + errx(1, "too many GLSL files"); + stage = MESA_SHADER_FRAGMENT; + } else if (strcmp(ext, ".vert") == 0) { + if (s.from_tgsi) + errx(1, "cannot mix GLSL and TGSI"); + if (num_files >= ARRAY_SIZE(filenames)) + errx(1, "too many GLSL files"); + stage = MESA_SHADER_VERTEX; + } else { + print_usage(); + return -1; + } + + filenames[num_files++] = filename; + + n++; + } + + nir_shader *nir; + + compiler = ir3_compiler_create(NULL, gpu_id); + + if (s.from_tgsi) { + struct tgsi_token toks[65536]; + + ret = read_file(filenames[0], &ptr, &size); + if (ret) { + print_usage(); + return ret; + } + + if (ir3_shader_debug & IR3_DBG_OPTMSGS) + debug_printf("%s\n", (char *)ptr); + + if (!tgsi_text_translate(ptr, toks, ARRAY_SIZE(toks))) + errx(1, "could not parse `%s'", filenames[0]); + + if (ir3_shader_debug & IR3_DBG_OPTMSGS) + tgsi_dump(toks, 0); + + nir = ir3_tgsi_to_nir(compiler, toks); + NIR_PASS_V(nir, nir_lower_global_vars_to_local); + } else if (from_spirv) { + nir = load_spirv(filenames[0], entry, stage); + + NIR_PASS_V(nir, nir_lower_io, nir_var_all, ir3_glsl_type_size, + (nir_lower_io_options)0); + + /* TODO do this somewhere else */ + nir_lower_int64(nir, ~0); + nir_lower_system_values(nir); + } else if (num_files > 0) { + nir = load_glsl(num_files, filenames, stage); + } else { + print_usage(); + return -1; + } + + s.compiler = compiler; + s.nir = ir3_optimize_nir(&s, nir, NULL); + + v.key = key; + v.shader = &s; + s.type = v.type = nir->info.stage; + + info = "NIR compiler"; + ret = ir3_compile_shader_nir(s.compiler, &v); + if (ret) { + fprintf(stderr, "compiler failed!\n"); + return ret; + } + dump_info(&v, info); +} diff --git a/mesa.spec b/mesa.spec index 044c434..cea8c1e 100644 --- a/mesa.spec +++ b/mesa.spec @@ -22,6 +22,7 @@ %ifarch %{arm} aarch64 %global with_etnaviv 1 %global with_freedreno 1 +%global with_kmsro 1 %global with_tegra 1 %global with_vc4 1 %global with_xa 1 @@ -62,6 +63,8 @@ Source3: Makefile # Source4 contains email correspondence clarifying the license terms. # Fedora opts to ignore the optional part of clause 2 and treat that code as 2 clause BSD. Source4: Mesa-MLAA-License-Clarification-Email.txt +Source5: freedreno-meson.build +Source6: ir3_cmdline.c Patch3: 0003-evergreen-big-endian.patch @@ -364,6 +367,9 @@ Headers for development with the Vulkan API. %endif cp %{SOURCE4} docs/ +# Nasty hack to fix build, reported to upstream freedreno maintainer for upstream make dist fix +cp %{SOURCE5} src/freedreno/meson.build +cp %{SOURCE6} src/gallium/drivers/freedreno/ir3/ir3_cmdline.c %build %if !0%{sanitize} @@ -376,7 +382,7 @@ cp %{SOURCE4} docs/ -Ddri3=true \ -Ddri-drivers=%{?dri_drivers} \ %if 0%{?with_hardware} - -Dgallium-drivers=swrast,virgl,r300,nouveau%{?with_vmware:,svga}%{?with_radeonsi:,radeonsi,r600}%{?with_freedreno:,freedreno}%{?with_etnaviv:,etnaviv,kmsro}%{?with_tegra:,tegra}%{?with_vc4:,vc4,kmsro} \ + -Dgallium-drivers=swrast,virgl,r300,nouveau%{?with_vmware:,svga}%{?with_radeonsi:,radeonsi,r600}%{?with_freedreno:,freedreno}%{?with_etnaviv:,etnaviv}%{?with_tegra:,tegra}%{?with_vc4:,vc4}%{?with_kmsro:,kmsro} \ %else -Dgallium-drivers=swrast,virgl \ %endif @@ -590,6 +596,10 @@ popd %dir %{_libdir}/gallium-pipe %{_libdir}/gallium-pipe/*.so %endif +%if 0%{?with_kmsro} +%{_libdir}/dri/hx8357d_dri.so +%{_libdir}/dri/pl111_dri.so +%endif %{_libdir}/dri/kms_swrast_dri.so %{_libdir}/dri/swrast_dri.so %{_libdir}/dri/virtio_gpu_dri.so