summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/gpgpu_shader.c40
-rw-r--r--lib/gpgpu_shader.h25
-rw-r--r--lib/iga64_generated_codes.c6
-rw-r--r--lib/iga64_macros.h16
-rw-r--r--lib/meson.build17
-rw-r--r--meson.build9
-rwxr-xr-xscripts/generate_iga64_codes129
-rw-r--r--scripts/meson.build1
8 files changed, 239 insertions, 4 deletions
diff --git a/lib/gpgpu_shader.c b/lib/gpgpu_shader.c
index 3b5ba8222..62171952e 100644
--- a/lib/gpgpu_shader.c
+++ b/lib/gpgpu_shader.c
@@ -11,6 +11,9 @@
#include "gpgpu_shader.h"
#include "gpu_cmds.h"
+#define IGA64_ARG0 0xc0ded000
+#define IGA64_ARG_MASK 0xffffff00
+
#define SUPPORTED_GEN_VER 1200 /* Support TGL and up */
#define PAGE_SIZE 4096
@@ -22,6 +25,43 @@
#define GPGPU_CURBE_SIZE 0
#define GEN7_VFE_STATE_GPGPU_MODE 1
+static void gpgpu_shader_extend(struct gpgpu_shader *shdr)
+{
+ shdr->max_size <<= 1;
+ shdr->code = realloc(shdr->code, 4 * shdr->max_size);
+ igt_assert(shdr->code);
+}
+
+void
+__emit_iga64_code(struct gpgpu_shader *shdr, struct iga64_template const *tpls,
+ int argc, uint32_t *argv)
+{
+ uint32_t *ptr;
+
+ igt_require_f(shdr->gen_ver >= SUPPORTED_GEN_VER,
+ "No available shader templates for platforms older than XeLP\n");
+
+ while (shdr->gen_ver < tpls->gen_ver)
+ tpls++;
+
+ while (shdr->max_size < shdr->size + tpls->size)
+ gpgpu_shader_extend(shdr);
+
+ ptr = shdr->code + shdr->size;
+ memcpy(ptr, tpls->code, 4 * tpls->size);
+
+ /* patch the template */
+ for (int n, i = 0; i < tpls->size; ++i) {
+ if ((ptr[i] & IGA64_ARG_MASK) != IGA64_ARG0)
+ continue;
+ n = ptr[i] - IGA64_ARG0;
+ igt_assert(n < argc);
+ ptr[i] = argv[n];
+ }
+
+ shdr->size += tpls->size;
+}
+
static uint32_t fill_sip(struct intel_bb *ibb,
const uint32_t sip[][4],
const size_t size)
diff --git a/lib/gpgpu_shader.h b/lib/gpgpu_shader.h
index 02f6f1aad..255f93b4d 100644
--- a/lib/gpgpu_shader.h
+++ b/lib/gpgpu_shader.h
@@ -23,6 +23,27 @@ struct gpgpu_shader {
};
};
+struct iga64_template {
+ uint32_t gen_ver;
+ uint32_t size;
+ const uint32_t *code;
+};
+
+#pragma GCC diagnostic ignored "-Wnested-externs"
+
+void
+__emit_iga64_code(struct gpgpu_shader *shdr, const struct iga64_template *tpls,
+ int argc, uint32_t *argv);
+
+#define emit_iga64_code(__shdr, __name, __txt, __args...) \
+({ \
+ static const char t[] __attribute__ ((section(".iga64_assembly"), used)) =\
+ "iga64_assembly_" #__name ":" __txt "\n"; \
+ extern struct iga64_template const iga64_code_ ## __name[]; \
+ u32 args[] = { __args }; \
+ __emit_iga64_code(__shdr, iga64_code_ ## __name, ARRAY_SIZE(args), args); \
+})
+
struct gpgpu_shader *gpgpu_shader_create(int fd);
void gpgpu_shader_destroy(struct gpgpu_shader *shdr);
@@ -35,4 +56,8 @@ void gpgpu_shader_exec(struct intel_bb *ibb,
struct gpgpu_shader *sip,
uint64_t ring, bool explicit_engine);
+void gpgpu_shader__eot(struct gpgpu_shader *shdr);
+void gpgpu_shader__write_dword(struct gpgpu_shader *shdr, uint32_t value,
+ uint32_t y_offset);
+
#endif /* GPGPU_SHADER_H */
diff --git a/lib/iga64_generated_codes.c b/lib/iga64_generated_codes.c
new file mode 100644
index 000000000..452d4b3da
--- /dev/null
+++ b/lib/iga64_generated_codes.c
@@ -0,0 +1,6 @@
+// SPDX-License-Identifier: MIT
+// Generated using Intel Graphics Assembler 1.1.0-int
+
+#include "gpgpu_shader.h"
+
+#define MD5_SUM_IGA64_ASMS 68b329da9893e34099c7d8ad5cb9c940
diff --git a/lib/iga64_macros.h b/lib/iga64_macros.h
new file mode 100644
index 000000000..f4ef5cb16
--- /dev/null
+++ b/lib/iga64_macros.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: MIT */
+/* Copyright © 2024 Intel Corporation */
+
+/* Header used during pre-process phase of iga64 assembly. */
+
+#ifndef IGA64_MACROS_H
+#define IGA64_MACROS_H
+
+/* send instruction for DG2+ requires 0 length in case src1 is null, BSpec: 47443 */
+#if GEN_VER < 1271
+#define src1_null null
+#else
+#define src1_null null:0
+#endif
+
+#endif
diff --git a/lib/meson.build b/lib/meson.build
index 7dc99f718..8c032cbb6 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -216,7 +216,10 @@ lib_version = vcs_tag(input : 'version.h.in', output : 'version.h',
fallback : 'NO-GIT',
command : vcs_command )
+iga64_assembly_sources = [ 'gpgpu_shader.c' ]
+
lib_intermediates = []
+iga64_assembly_libs = []
foreach f: lib_sources
name = f.underscorify()
lib = static_library('igt-' + name,
@@ -230,8 +233,22 @@ foreach f: lib_sources
])
lib_intermediates += lib
+ if iga64_assembly_sources.contains(f)
+ iga64_assembly_libs += lib
+ endif
endforeach
+iga64_generated_codes = custom_target(
+ 'iga64_generated_codes.c',
+ input : [ 'iga64_generated_codes.c' ] + iga64_assembly_libs,
+ output : 'iga64_generated_codes.c',
+ command : [ generate_iga64_codes, '-o', '@OUTPUT@', '-i', '@INPUT@' ]
+)
+
+lib_intermediates += static_library('igt-iga64_generated_codes.c',
+ [ iga64_generated_codes, lib_version ]
+ )
+
lib_igt_build = shared_library('igt',
['dummy.c'],
link_whole: lib_intermediates,
diff --git a/meson.build b/meson.build
index 6ae3c2684..25bf1e442 100644
--- a/meson.build
+++ b/meson.build
@@ -357,6 +357,11 @@ else
vmwgfx_rpathdir = ''
endif
+build_testplan = get_option('testplan')
+build_sphinx = get_option('sphinx')
+
+subdir('scripts')
+
subdir('lib')
if build_tests
subdir('tests')
@@ -365,9 +370,6 @@ else
endif
build_info += 'Build tests: @0@'.format(build_tests)
-build_testplan = get_option('testplan')
-build_sphinx = get_option('sphinx')
-
subdir('benchmarks')
subdir('tools')
subdir('runner')
@@ -376,7 +378,6 @@ if libdrm_intel.found()
endif
subdir('overlay')
subdir('man')
-subdir('scripts')
subdir('docs')
message('Build options')
diff --git a/scripts/generate_iga64_codes b/scripts/generate_iga64_codes
new file mode 100755
index 000000000..3d114ea0e
--- /dev/null
+++ b/scripts/generate_iga64_codes
@@ -0,0 +1,129 @@
+#!/bin/bash
+# SPDX-License-Identifier: MIT
+# Copyright © 2024 Intel Corporation
+# Author: Andrzej Hajda <andrzej.hajda@intel.com>
+
+# List of supported platforms, in format gen100:platform, where gen100 equals
+# to minimal GPU generation supported by platform multiplied by 100 and platform
+# is one of platforms supported by -p switch of iga64.
+# Must be in decreasing order, the last one must have gen100 equal 0.
+GEN_VERSIONS="2000:2 1272:12p72 1250:12p5 0:12p1"
+
+# Magic values to encode asm template args, must be the the same as in gpgpu_shader.c.
+IGA64_ARG0=0xc0ded000
+IGA64_ARG_MASK=0xffffff00
+
+warn() {
+ echo -e "$1" >/dev/stderr
+}
+
+die() {
+ warn "DIE: $1"
+ exit 1
+}
+
+# parse args
+while getopts ':i:o:' opt; do
+ case $opt in
+ i) INPUT=$OPTARG;;
+ o) OUTPUT=$OPTARG;;
+ ?) die "Usage: $0 -i pre-generated-iga64-file -o generated-iga64-file libs-with-iga64-assembly [...]"
+ esac
+done
+LIBS=${@:OPTIND}
+
+# read all assemblies into ASMS array
+ASMS=()
+while read -d $'\0' asm; do
+ test -z "$asm" && continue
+ ASMS+=( "$asm" )
+done < <(for f in $LIBS; do objcopy --dump-section .iga64_assembly=/dev/stdout $f.p/*.o; done)
+
+# check if we need to recompile - checksum difference and compiler present
+MD5_ASMS="$(md5sum <<< "${ASMS[@]}" | cut -b1-32)"
+MD5_PRE="$(grep -Po '(?<=^#define MD5_SUM_IGA64_ASMS )\S{32,32}' $INPUT 2>/dev/null)"
+
+if [ "$MD5_ASMS" = "$MD5_PRE" ]; then
+ echo "iga64 assemblies not changed, reusing pre-compiled file $INPUT."
+ cp $INPUT $OUTPUT
+ exit 0
+fi
+
+type iga64 >/dev/null || {
+ warn "WARNING: iga64 assemblies changed, but iga64 compiler not present, CHANGES will have no effect. Install iga64 (libigc-tools package) to re-compile code."
+ cp $INPUT $OUTPUT
+ exit 0
+}
+
+# generate code file
+WD=$OUTPUT.d
+mkdir -p $WD
+
+# check if all required platforms are supported
+touch $WD/empty
+for gen in $GEN_VERSIONS; do
+ gen_name="${gen#*:}"
+ iga64 -p=$gen_name -d $WD/empty 2>/dev/null || {
+ warn "WARNING: iga64 assemblies changed, but iga64 compiler does not support platform '$gen_name', CHANGES will have no effect. Update iga64 (libigc-tools package) to re-compile code."
+ cp $INPUT $OUTPUT
+ exit 0
+ }
+done
+
+# returns count of numbers in strings of format "0x1234, 0x23434, ..."
+dword_count() {
+ n=${1//[^x]}
+ echo ${#n}
+}
+
+echo "Generating new $OUTPUT"
+
+cat <<-EOF >$OUTPUT
+// SPDX-License-Identifier: MIT
+// Generated using $(iga64 |& head -1)
+
+#include "gpgpu_shader.h"
+
+#define MD5_SUM_IGA64_ASMS $MD5_ASMS
+EOF
+
+# Compiles assembly to binary representation sent to stdout.
+compile_iga64() {
+ cmd="cpp -P - -o $WD/$asm_name.$gen_name.asm"
+ cmd+=" -DGEN_VER=$gen_ver -D'ARG(n)=($IGA64_ARG0 + (n))' -imacros ../lib/iga64_macros.h"
+ eval "$cmd" <<<"$asm_body" || die "cpp error for $asm_name.$gen_name\ncmd: $cmd"
+ cmd="iga64 -Xauto-deps -Wall -p=$gen_name"
+ cmd+=" $WD/$asm_name.$gen_name.asm"
+ warn "$cmd"
+ eval "$cmd" || die "iga64 error for $asm_name.$gen_name\ncmd: $cmd"
+}
+
+for asm in "${ASMS[@]}"; do
+ asm_name="${asm%%:*}"
+ asm_code="${asm_name/assembly/code}"
+ asm_body="${asm#*:}"
+ cur_code=""
+ cur_ver=""
+ echo -e "\nstruct iga64_template const $asm_code[] = {" >>$OUTPUT
+ for gen in $GEN_VERSIONS; do
+ gen_ver="${gen%%:*}"
+ gen_name="${gen#*:}"
+ warn "Generating $asm_code for platform $gen_name"
+ # Verify generated code will not contain IGA64_ARGs.
+ for d in $(IGA64_ARG0=0 compile_iga64 | hexdump -v -e '1/4 "0x%08x\n"'); do
+ (( (d & IGA64_ARG_MASK) == IGA64_ARG0 )) || continue
+ die "Assembly for $asm_name.$gen_name contains instruction which compiles to $d, conflicts with IGA64_ARG0/mask $IGA64_ARG0/$IGA64_ARG_MASK\ncmd: $cmd"
+ done
+ compile_iga64 > "$WD/$asm_name.$gen_name.bin" || die "Cannot write to $WD/$asm_name.$gen_name.bin"
+ code="$(hexdump -v -e '"\t\t" 4/4 "0x%08x, " "\n"' $WD/$asm_name.$gen_name.bin)"
+ [ -z "$cur_code" ] && cur_code="$code"
+ [ "$cur_code" != "$code" ] && {
+ echo -e "\t{ .gen_ver = $cur_ver, .size = $(dword_count "$cur_code"), .code = (const uint32_t []) {\n$cur_code\n\t}}," >>$OUTPUT
+ cur_code="$code"
+ }
+ cur_ver=$gen_ver
+ done
+ echo -e "\t{ .gen_ver = $cur_ver, .size = $(dword_count "$cur_code"), .code = (const uint32_t []) {\n$cur_code\n\t}}\n};" >>$OUTPUT
+done
+
+cp $OUTPUT $INPUT
diff --git a/scripts/meson.build b/scripts/meson.build
index 98783222b..6e64065c5 100644
--- a/scripts/meson.build
+++ b/scripts/meson.build
@@ -14,3 +14,4 @@ endif
igt_doc_script = find_program('igt_doc.py', required : build_testplan)
gen_rst_index = find_program('gen_rst_index', required : build_sphinx)
+generate_iga64_codes = find_program('generate_iga64_codes')