From 7e82b85d195d90c4aa5d10dd820463197db89615 Mon Sep 17 00:00:00 2001 From: elwrcl Date: Tue, 21 Jul 2026 14:26:36 +0300 Subject: [PATCH] wip: crocus/rusticl/elk/hasvk local changes before h264 cherry-pick --- flake.lock | 27 ++ flake.nix | 242 +++++++++--- src/gallium/drivers/crocus/crocus_batch.c | 12 +- src/gallium/drivers/crocus/crocus_batch.h | 1 + src/gallium/drivers/crocus/crocus_context.h | 2 + src/gallium/drivers/crocus/crocus_draw.c | 9 +- src/gallium/drivers/crocus/crocus_formats.c | 14 +- src/gallium/drivers/crocus/crocus_program.c | 363 +++++++++++++++++- src/gallium/drivers/crocus/crocus_screen.c | 82 ++-- src/gallium/drivers/crocus/crocus_state.c | 113 +++++- src/gallium/frontends/rusticl/api/context.rs | 22 +- src/gallium/frontends/rusticl/api/device.rs | 10 +- src/gallium/frontends/rusticl/api/memory.rs | 17 + src/gallium/frontends/rusticl/core/device.rs | 21 +- src/gallium/frontends/rusticl/core/kernel.rs | 3 + src/gallium/frontends/rusticl/core/queue.rs | 1 + src/gallium/include/pipe/p_defines.h | 1 + src/intel/compiler/elk/elk_compiler.c | 4 + src/intel/compiler/elk/elk_compiler.h | 1 + src/intel/compiler/elk/elk_fs_nir.cpp | 75 +++- .../compiler/elk/elk_lower_logical_sends.cpp | 3 +- src/intel/compiler/elk/elk_nir.c | 54 ++- src/intel/compiler/elk/elk_reg_type.c | 10 +- .../intel_device_info.cpython-313.pyc | Bin 0 -> 19913 bytes .../intel_device_info.cpython-314.pyc | Bin 0 -> 20452 bytes .../__pycache__/intel_genxml.cpython-313.pyc | Bin 0 -> 25369 bytes .../__pycache__/intel_genxml.cpython-314.pyc | Bin 0 -> 28220 bytes .../genxml/__pycache__/util.cpython-313.pyc | Bin 0 -> 706 bytes .../genxml/__pycache__/util.cpython-314.pyc | Bin 0 -> 739 bytes src/intel/vulkan_hasvk/anv_batch_chain.c | 99 ++++- src/intel/vulkan_hasvk/anv_image.c | 7 +- src/intel/vulkan_hasvk/anv_private.h | 51 +++ src/intel/vulkan_hasvk/genX_cmd_buffer.c | 82 +++- src/intel/vulkan_hasvk/genX_pipeline.c | 34 ++ src/intel/vulkan_hasvk/gfx7_cmd_buffer.c | 8 +- 35 files changed, 1177 insertions(+), 191 deletions(-) create mode 100644 flake.lock create mode 100644 src/intel/dev/__pycache__/intel_device_info.cpython-313.pyc create mode 100644 src/intel/dev/__pycache__/intel_device_info.cpython-314.pyc create mode 100644 src/intel/genxml/__pycache__/intel_genxml.cpython-313.pyc create mode 100644 src/intel/genxml/__pycache__/intel_genxml.cpython-314.pyc create mode 100644 src/intel/genxml/__pycache__/util.cpython-313.pyc create mode 100644 src/intel/genxml/__pycache__/util.cpython-314.pyc diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..fb043dc --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1784007870, + "narHash": "sha256-djcLt/JJphyNt4eDY9XTly+/WbCK5lqWq9lSgCmJkkQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "18b9261cb3294b6d2a06d03f96872827b8fe2698", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix index c65f719..968b63f 100644 --- a/flake.nix +++ b/flake.nix @@ -1,58 +1,200 @@ { - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - flake-utils.url = "github:numtide/flake-utils"; - }; + description = "intel-hard-graphics / clvk development"; + inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; outputs = + { self, nixpkgs }: + let + system = "x86_64-linux"; + pkgs = import nixpkgs { inherit system; }; + + # HD 4000 (Gen7) PCI ID: 8086:0166 + pciId = "8086:0166"; + defaultClvkBuildDir = "/home/elars/ProjectsHDD/Drivers/clvk/build"; + + commonBuildInputs = with pkgs; [ + llvmPackages_21.clang-unwrapped + llvmPackages_21.llvm.dev + llvmPackages_21.libclang + llvmPackages_21.bintools + python3Packages.packaging + python3Packages.pyyaml + python3Packages.mako + python3 + cargo + meson + ninja + pkg-config + spirv-llvm-translator + spirv-tools + rust-bindgen + rustc + vkmark + vulkan-headers + vulkan-loader + vulkan-tools + shaderc + libpciaccess + opencl-headers + libclc + bison + flex + libdrm + libelf + expat + zlib + zstd + libx11 + ocl-icd + libxcb + cmake + libxext + libxfixes + libxrandr + libxshmfence + wayland + wayland-protocols + wayland-scanner + xorgproto + xorg.libXxf86vm + xorg.xcbutilkeysyms + (python3.withPackages ( + ps: with ps; [ + pyopencl + opencv4 + numpy + ] + )) + clinfo + strace + clpeak + pocl + gdb + ]; + + commonShellVars = '' + export LIBRARY_PATH=${pkgs.llvmPackages_21.clang-unwrapped.lib}/lib:$LIBRARY_PATH + export LIBCLANG_PATH=${pkgs.llvmPackages_21.libclang.lib}/lib + export BINDGEN_EXTRA_CLANG_ARGS="-I${pkgs.llvmPackages_21.clang-unwrapped}/lib/clang/21/include" + export C_INCLUDE_PATH=${pkgs.opencl-headers}/include:$C_INCLUDE_PATH + export LIBRARY_PATH=${pkgs.ocl-icd}/lib:$LIBRARY_PATH + export LD_LIBRARY_PATH="${pkgs.vulkan-loader}/lib:$LD_LIBRARY_PATH" + ''; + + # 32-bit (i686) build için: L4D2 gibi 32-bit oyunlarla test amaçlı. + # clvk/rusticl/OpenCL burada yok — sadece hasvk (vulkan_hasvk) + crocus + # için gereken Vulkan/GL/WSI kütüphaneleri, i686 varyantlarıyla. + pkgs32 = pkgs.pkgsi686Linux; + + i686BuildInputs = with pkgs32; [ + libdrm + libelf + libpciaccess + expat + zlib + zstd + libx11 + libxcb + libxext + libxfixes + libxrandr + libxshmfence + wayland + wayland-protocols + xorgproto + xorg.libXxf86vm + xorg.xcbutilkeysyms + vulkan-headers + vulkan-loader + llvmPackages_21.llvm.dev + llvmPackages_21.clang-unwrapped + llvmPackages_21.libclang + spirv-llvm-translator + spirv-tools + libclc + # crocus + hasvk (with_driver_using_cl) libclc'ye hard-dependency, + # rusticl/opencl kapalı olsa bile gerekiyor + ]; + + # Build araçları (meson/ninja/python/bison/flex/pkg-config vs.) i686'da + # da bulunur ama host mimarisinde çalıştırılmaları yeterli; yine de + # pkgsi686Linux'tan almak pkg-config'in .pc arama yollarını tutarlı + # tutar. cmake/rust burada gerekmiyor (clvk 32-bit hedefi değil). + i686NativeBuildInputs = with pkgs32; [ + meson + ninja + pkg-config + python3 + python3Packages.packaging + python3Packages.pyyaml + python3Packages.mako + bison + flex + wayland-scanner + ]; + in { - self, - nixpkgs, - flake-utils, - }: - flake-utils.lib.eachDefaultSystem ( - system: - let - pkgs = nixpkgs.legacyPackages.${system}; - llvmPkgs = pkgs.llvmPackages_19; - in - { - devShells.default = pkgs.mkShell { - name = "mesa-crocus-opencl"; - - packages = with pkgs; [ - # build tools - meson - ninja - pkg-config - cmake - python3 - python3Packages.packaging - - # LLVM stack - llvmPkgs.llvm.dev - llvmPkgs.clang - llvmPkgs.libclc - - # Rust - rust-bindgen - rustc - cargo - - # Mesa deps - libdrm - expat - zlib - zstd - glslang - libffi - elfutils - ]; - + devShells.${system} = { + # nix develop = intel-hard-graphics shell + default = pkgs.mkShell { + buildInputs = commonBuildInputs; shellHook = '' - export PKG_CONFIG_PATH=${pkgs.llvmPackages_19.libclc}/share/pkgconfig:$PKG_CONFIG_PATH + ${commonShellVars} + export LD_LIBRARY_PATH=$PWD/build/src/gallium/targets/rusticl:$LD_LIBRARY_PATH + export RUSTICL_ENABLE=crocus + + mkdir -p $PWD/.icd-vendors + ln -sf $PWD/build/src/gallium/targets/rusticl/rusticl.icd $PWD/.icd-vendors/rusticl.icd + ln -sf ${pkgs.pocl}/etc/OpenCL/vendors/pocl.icd $PWD/.icd-vendors/pocl.icd + export OCL_ICD_VENDORS=$PWD/.icd-vendors + + echo "=== intel-hard-graphics ===" + echo "OCL_ICD_VENDORS=$OCL_ICD_VENDORS" + echo "RUSTICL_ENABLE=$RUSTICL_ENABLE" + echo "" ''; }; - } - ); + # nix develop .#clvk = clvk shell + clvk = pkgs.mkShell { + buildInputs = commonBuildInputs; + shellHook = '' + ${commonShellVars} + + CLVK_BUILD_DIR="''${CLVK_BUILD_DIR:-${defaultClvkBuildDir}}" + + if [ ! -d "$CLVK_BUILD_DIR" ]; then + echo "UYARI: clvk build dizini bulunamadi: $CLVK_BUILD_DIR" + echo "CLVK_BUILD_DIR ortam degiskeniyle dogru yolu ver, ornek:" + echo " CLVK_BUILD_DIR=/gercek/yol nix develop .#clvk" + else + export LD_LIBRARY_PATH="$CLVK_BUILD_DIR:$LD_LIBRARY_PATH" + fi + + export MESA_VK_DEVICE_SELECT="${pciId}" + + echo "=== clvk ===" + echo "CLVK_BUILD_DIR=$CLVK_BUILD_DIR" + echo "MESA_VK_DEVICE_SELECT=$MESA_VK_DEVICE_SELECT" + echo "" + ''; + }; + # nix develop .#i686 = 32-bit hasvk/crocus build shell (L4D2 testi için) + i686 = pkgs32.mkShell { + buildInputs = i686BuildInputs; + nativeBuildInputs = i686NativeBuildInputs; + shellHook = '' + export MESA_VK_DEVICE_SELECT="${pciId}" + + echo "=== intel-hard-graphics (i686 / 32-bit) ===" + echo "CC=$CC" + echo "meson setup build32 --buildtype=debugoptimized \\" + echo " -Dgallium-drivers=crocus -Dvulkan-drivers=intel_hasvk \\" + echo " -Dplatforms=x11 -Degl=disabled -Dglx=disabled -Dgbm=disabled \\" + echo " -Dopengl=false -Dgles1=disabled -Dgles2=disabled \\" + echo " -Dgallium-rusticl=false -Dmicrosoft-clc=disabled -Dllvm=enabled" + echo "" + ''; + }; + }; + }; } diff --git a/src/gallium/drivers/crocus/crocus_batch.c b/src/gallium/drivers/crocus/crocus_batch.c index 868a72b..d2db3c3 100644 --- a/src/gallium/drivers/crocus/crocus_batch.c +++ b/src/gallium/drivers/crocus/crocus_batch.c @@ -301,7 +301,7 @@ ensure_exec_obj_space(struct crocus_batch *batch, uint32_t count) } } -static struct drm_i915_gem_exec_object2 * +struct drm_i915_gem_exec_object2 * crocus_use_bo(struct crocus_batch *batch, struct crocus_bo *bo, bool writable) { assert(bo->bufmgr == batch->command.bo->bufmgr); @@ -458,7 +458,10 @@ recreate_growing_buffer(struct crocus_batch *batch, struct crocus_screen *screen = batch->screen; struct crocus_bufmgr *bufmgr = screen->bufmgr; grow->bo = crocus_bo_alloc(bufmgr, name, size); - grow->bo->kflags |= EXEC_OBJECT_CAPTURE; + static uint64_t next_grow_pin = 0x20000000ULL; /* 512MB */ + grow->bo->gtt_offset = next_grow_pin; + next_grow_pin += align64(size, 4096); + grow->bo->kflags |= EXEC_OBJECT_CAPTURE | EXEC_OBJECT_PINNED; grow->partial_bo = NULL; grow->partial_bo_map = NULL; grow->partial_bytes = 0; @@ -903,8 +906,9 @@ submit_batch(struct crocus_batch *batch) DBG("BO %d migrated: 0x%" PRIx64 " -> 0x%" PRIx64 "\n", bo->gem_handle, bo->gtt_offset, (uint64_t)batch->validation_list[i].offset); - assert(!(bo->kflags & EXEC_OBJECT_PINNED)); - bo->gtt_offset = batch->validation_list[i].offset; + if (!(bo->kflags & EXEC_OBJECT_PINNED)) { + bo->gtt_offset = batch->validation_list[i].offset; + } } } diff --git a/src/gallium/drivers/crocus/crocus_batch.h b/src/gallium/drivers/crocus/crocus_batch.h index ae2f8aa..4e1efcc 100644 --- a/src/gallium/drivers/crocus/crocus_batch.h +++ b/src/gallium/drivers/crocus/crocus_batch.h @@ -200,6 +200,7 @@ bool crocus_batch_prepare_noop(struct crocus_batch *batch, bool noop_enable); /* Inverted meaning, but using the same bit...emit_reloc will flip it. */ #define RELOC_32BIT EXEC_OBJECT_SUPPORTS_48B_ADDRESS +struct drm_i915_gem_exec_object2 *crocus_use_bo(struct crocus_batch *batch, struct crocus_bo *bo, bool writable); void crocus_use_pinned_bo(struct crocus_batch *batch, struct crocus_bo *bo, bool writable); uint64_t crocus_command_reloc(struct crocus_batch *batch, uint32_t batch_offset, diff --git a/src/gallium/drivers/crocus/crocus_context.h b/src/gallium/drivers/crocus/crocus_context.h index 3efc069..ff495b6 100644 --- a/src/gallium/drivers/crocus/crocus_context.h +++ b/src/gallium/drivers/crocus/crocus_context.h @@ -339,6 +339,7 @@ enum crocus_surface_group { CROCUS_SURFACE_GROUP_IMAGE, CROCUS_SURFACE_GROUP_UBO, CROCUS_SURFACE_GROUP_SSBO, + CROCUS_SURFACE_GROUP_GLOBAL, CROCUS_SURFACE_GROUP_COUNT, }; @@ -608,6 +609,7 @@ struct crocus_context { struct crocus_state_ref grid_size; /** Global bindings for compute */ struct pipe_resource *global_bindings[CROCUS_MAX_GLOBAL_BINDINGS]; + uint32_t *global_binding_handles[CROCUS_MAX_GLOBAL_BINDINGS]; /** * Array of aux usages for drawing, altered to account for any diff --git a/src/gallium/drivers/crocus/crocus_draw.c b/src/gallium/drivers/crocus/crocus_draw.c index 3b3d73d..9879682 100644 --- a/src/gallium/drivers/crocus/crocus_draw.c +++ b/src/gallium/drivers/crocus/crocus_draw.c @@ -517,9 +517,16 @@ crocus_launch_grid(struct pipe_context *ctx, const struct pipe_grid_info *grid) crocus_handle_always_flush_cache(batch); + for (unsigned i = 0; i < CROCUS_MAX_GLOBAL_BINDINGS; i++) { + if (ice->state.global_bindings[i]) { + struct crocus_resource *res = (struct crocus_resource *)ice->state.global_bindings[i]; + crocus_use_bo(batch, res->bo, true); + } + } + screen->vtbl.upload_compute_state(ice, batch, grid); - crocus_handle_always_flush_cache(batch); + crocus_flush_all_caches(batch); ice->state.dirty &= ~CROCUS_ALL_DIRTY_FOR_COMPUTE; ice->state.stage_dirty &= ~CROCUS_ALL_STAGE_DIRTY_FOR_COMPUTE; diff --git a/src/gallium/drivers/crocus/crocus_formats.c b/src/gallium/drivers/crocus/crocus_formats.c index 29b3232..aaebaba 100644 --- a/src/gallium/drivers/crocus/crocus_formats.c +++ b/src/gallium/drivers/crocus/crocus_formats.c @@ -509,10 +509,18 @@ crocus_is_format_supported(struct pipe_screen *pscreen, /* Dataport doesn't support compression, and we can't resolve an MCS * compressed surface. (Buffer images may have sample count of 0.) */ - supported &= sample_count == 0; + bool sc_ok = sample_count == 0; + bool tw_ok = isl_format_supports_typed_writes(devinfo, format); + bool ts_ok = isl_has_matching_typed_storage_image_format(devinfo, format); + supported &= sc_ok && tw_ok && ts_ok; - supported &= isl_format_supports_typed_writes(devinfo, format); - supported &= isl_has_matching_typed_storage_image_format(devinfo, format); + FILE *dbgf = fopen("/tmp/crocus_debug.log", "a"); + if (dbgf) { + fprintf(dbgf, "CROCUS_DBG: shader_image check pformat=%d target=%d sample_count=%u " + "isl_format=%d sc_ok=%d tw_ok=%d ts_ok=%d supported=%d\n", + pformat, target, sample_count, format, sc_ok, tw_ok, ts_ok, supported); + fclose(dbgf); + } } if (usage & PIPE_BIND_SAMPLER_VIEW) { diff --git a/src/gallium/drivers/crocus/crocus_program.c b/src/gallium/drivers/crocus/crocus_program.c index b17ed02..6209d5c 100644 --- a/src/gallium/drivers/crocus/crocus_program.c +++ b/src/gallium/drivers/crocus/crocus_program.c @@ -714,6 +714,7 @@ static const char *surface_group_names[] = { [CROCUS_SURFACE_GROUP_UBO] = "ubo", [CROCUS_SURFACE_GROUP_SSBO] = "ssbo", [CROCUS_SURFACE_GROUP_IMAGE] = "image", + [CROCUS_SURFACE_GROUP_GLOBAL] = "global (IVB)", }; static void @@ -842,7 +843,8 @@ crocus_setup_binding_table(const struct intel_device_info *devinfo, bt->used_mask[CROCUS_SURFACE_GROUP_RENDER_TARGET_READ] = BITFIELD64_MASK(num_render_targets); } - } else if (info->stage == MESA_SHADER_COMPUTE) { + } else if (info->stage == MESA_SHADER_COMPUTE || + info->stage == MESA_SHADER_KERNEL) { bt->sizes[CROCUS_SURFACE_GROUP_CS_WORK_GROUPS] = 1; } else if (info->stage == MESA_SHADER_GEOMETRY) { /* In gfx6 we reserve the first ELK_MAX_SOL_BINDINGS entries for transform @@ -2504,6 +2506,335 @@ crocus_update_compiled_shaders(struct crocus_context *ice) return true; } +/* IVB Gen7 doesn't support stateless global memory access (BTI 255 is only + * valid on Haswell+ / Gen7.5+). Instead of a dedicated global-memory BTI + * (limited to 64 slots, and unable to distinguish multiple __global buffer + * arguments since their kernel_input handles all resolve to address 0), + * redirect every load_global/store_global to load_ssbo/store_ssbo. + * + * The address of a global access is always kernel_input UBO offset N + * (optionally + a relative offset expression). N corresponds 1:1, in + * increasing order, to rusticl's start_slot ordering in + * crocus_set_global_binding() -- both are "the Nth __global buffer + * argument that's actually used", skipping dead/scalar arguments. So we + * assign SSBO index = rank of N among all distinct offsets seen. + */ +/* Pass 1 helper: find N in load_ubo(0,N), without building any new + * instructions (safe to call speculatively during discovery). Handles + * arbitrarily nested iadd chains, e.g. iadd(iadd(load_ubo(0,N), i*8), 4) + * which occurs for struct field access (out[i].b). */ +/* Recursively determines whether following iadd chains from `def` + * eventually reaches a load_ubo intrinsic. Unlike a shallow type check, + * this actually walks the chain so mul/bcsel/etc. on the *other* branch + * don't cause a false positive. */ +static bool +crocus_def_leads_to_ubo(nir_def *def) +{ + nir_instr *instr = nir_def_instr(def); + + if (instr->type == nir_instr_type_intrinsic && + nir_instr_as_intrinsic(instr)->intrinsic == nir_intrinsic_load_ubo) + return true; + + if (instr->type == nir_instr_type_phi) { + nir_phi_instr *phi = nir_instr_as_phi(instr); + nir_foreach_phi_src(phi_src, phi) { + if (!crocus_def_leads_to_ubo(phi_src->src.ssa)) + return false; + } + return true; + } + + if (instr->type != nir_instr_type_alu) + return false; + + nir_alu_instr *alu = nir_instr_as_alu(instr); + if (alu->op != nir_op_iadd) + return false; + + nir_def *lhs = alu->src[0].src.ssa; + nir_def *rhs = alu->src[1].src.ssa; + + return crocus_def_leads_to_ubo(lhs) || crocus_def_leads_to_ubo(rhs); +} + +static bool +crocus_global_addr_find_ubo_offset(nir_src *addr_src, uint32_t *out_offset) +{ + nir_def *cur = addr_src->ssa; + + for (;;) { + if (nir_def_instr(cur)->type == nir_instr_type_intrinsic && + nir_instr_as_intrinsic(nir_def_instr(cur))->intrinsic == + nir_intrinsic_load_ubo) { + nir_intrinsic_instr *ld_ubo = nir_instr_as_intrinsic(nir_def_instr(cur)); + if (!nir_src_is_const(ld_ubo->src[1])) + return false; + *out_offset = nir_src_as_uint(ld_ubo->src[1]); + return true; + } + + /* Control-flow merge: all phi sources must resolve to the + * same underlying UBO offset (i.e. the same buffer), only + * the runtime-computed relative offset may differ per branch. */ + if (nir_def_instr(cur)->type == nir_instr_type_phi) { + nir_phi_instr *phi = nir_instr_as_phi(nir_def_instr(cur)); + uint32_t phi_off; + bool first = true; + nir_foreach_phi_src(phi_src, phi) { + uint32_t src_off; + if (!crocus_global_addr_find_ubo_offset(&phi_src->src, &src_off)) + return false; + if (first) { + phi_off = src_off; + first = false; + } else if (src_off != phi_off) { + return false; + } + } + *out_offset = phi_off; + return true; + } + + if (nir_def_instr(cur)->type != nir_instr_type_alu) + return false; + + nir_alu_instr *alu = nir_instr_as_alu(nir_def_instr(cur)); + if (alu->op != nir_op_iadd) + return false; + + nir_def *lhs = alu->src[0].src.ssa; + nir_def *rhs = alu->src[1].src.ssa; + + if (crocus_def_leads_to_ubo(lhs)) + cur = lhs; + else if (crocus_def_leads_to_ubo(rhs)) + cur = rhs; + else + return false; + } +} + +/* Pass 2 helper: rebuild the full relative offset expression (sum of + * everything peeled off while descending to the load_ubo leaf). Must + * only be called with b.cursor already positioned before the real + * instruction being rewritten. */ +static nir_def * +crocus_global_addr_build_rel_offset(nir_builder *b, nir_src *addr_src) +{ + nir_def *cur = addr_src->ssa; + nir_def *sum = NULL; + + for (;;) { + if (nir_def_instr(cur)->type == nir_instr_type_intrinsic && + nir_instr_as_intrinsic(nir_def_instr(cur))->intrinsic == + nir_intrinsic_load_ubo) { + return sum ? sum : nir_imm_int(b, 0); + } + + if (nir_def_instr(cur)->type == nir_instr_type_phi) { + nir_phi_instr *phi = nir_instr_as_phi(nir_def_instr(cur)); + nir_phi_instr *new_phi = nir_phi_instr_create(b->shader); + nir_def_init(&new_phi->instr, &new_phi->def, 1, 32); + + nir_foreach_phi_src(phi_src, phi) { + nir_builder pb = *b; + pb.cursor = nir_after_block_before_jump(phi_src->pred); + nir_def *branch_off = + crocus_global_addr_build_rel_offset(&pb, &phi_src->src); + nir_phi_instr_add_src(new_phi, phi_src->pred, branch_off); + } + + nir_instr_insert_before(&phi->instr, &new_phi->instr); + nir_def *phi_result = &new_phi->def; + return sum ? nir_iadd(b, sum, phi_result) : phi_result; + } + + nir_alu_instr *alu = nir_instr_as_alu(nir_def_instr(cur)); + nir_def *lhs = alu->src[0].src.ssa; + nir_def *rhs = alu->src[1].src.ssa; + + bool follow_lhs = crocus_def_leads_to_ubo(lhs); + nir_def *peeled = follow_lhs ? rhs : lhs; + sum = sum ? nir_iadd(b, sum, peeled) : peeled; + cur = follow_lhs ? lhs : rhs; + } +} + +static bool +crocus_lower_cs_global_to_ssbo(nir_shader *nir) +{ + nir_function_impl *impl = nir_shader_get_entrypoint(nir); + + uint32_t offsets[64]; + unsigned num_offsets = 0; + + /* Pass 1: discover every distinct kernel_input offset used as a + * load_global/store_global base. */ + nir_foreach_block(block, impl) { + nir_foreach_instr(instr, block) { + if (instr->type != nir_instr_type_intrinsic) + continue; + nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); + + nir_src *addr_src; + switch (intrin->intrinsic) { + case nir_intrinsic_load_global: + case nir_intrinsic_load_global_constant: + addr_src = &intrin->src[0]; + break; + case nir_intrinsic_store_global: + addr_src = &intrin->src[1]; + break; + case nir_intrinsic_global_atomic: + case nir_intrinsic_global_atomic_swap: + addr_src = &intrin->src[0]; + break; + default: + continue; + } + + uint32_t off; + if (!crocus_global_addr_find_ubo_offset(addr_src, &off)) { + fprintf(stderr, "=== UNRECOGNIZED GLOBAL PATTERN (intrinsic: %s) ===\n", + nir_intrinsic_infos[intrin->intrinsic].name); + nir_print_instr(&intrin->instr, stderr); + fprintf(stderr, "\n--- addr_src def ---\n"); + nir_print_instr(nir_def_instr(addr_src->ssa), stderr); + fprintf(stderr, "\n"); + fflush(stderr); + assert(!"crocus: unrecognized __global address pattern on IVB"); + } + + + bool found = false; + for (unsigned i = 0; i < num_offsets; i++) { + if (offsets[i] == off) { + found = true; + break; + } + } + if (!found) { + assert(num_offsets < ARRAY_SIZE(offsets)); + offsets[num_offsets++] = off; + } + } + } + + if (num_offsets == 0) + return false; + + /* Sort ascending: SSBO index = rank, matching rusticl's start_slot order */ + for (unsigned i = 1; i < num_offsets; i++) { + uint32_t key = offsets[i]; + int j = i - 1; + while (j >= 0 && offsets[j] > key) { + offsets[j + 1] = offsets[j]; + j--; + } + offsets[j + 1] = key; + } + + /* Pass 2: rewrite load_global/store_global -> load_ssbo/store_ssbo */ + nir_builder b = nir_builder_create(impl); + + nir_foreach_block_safe(block, impl) { + nir_foreach_instr_safe(instr, block) { + if (instr->type != nir_instr_type_intrinsic) + continue; + nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); + + nir_src *addr_src; + enum { OP_LOAD, OP_STORE, OP_ATOMIC, OP_ATOMIC_SWAP } kind; + + switch (intrin->intrinsic) { + case nir_intrinsic_load_global: + case nir_intrinsic_load_global_constant: + kind = OP_LOAD; + addr_src = &intrin->src[0]; + break; + case nir_intrinsic_store_global: + kind = OP_STORE; + addr_src = &intrin->src[1]; + break; + case nir_intrinsic_global_atomic: + kind = OP_ATOMIC; + addr_src = &intrin->src[0]; + break; + case nir_intrinsic_global_atomic_swap: + kind = OP_ATOMIC_SWAP; + addr_src = &intrin->src[0]; + break; + default: + continue; + } + + b.cursor = nir_before_instr(instr); + + uint32_t off; + if (!crocus_global_addr_find_ubo_offset(addr_src, &off)) + assert(!"crocus: unrecognized __global address pattern on IVB"); + + nir_def *rel = crocus_global_addr_build_rel_offset(&b, addr_src); + + unsigned ssbo_idx = 0; + bool found = false; + for (unsigned i = 0; i < num_offsets; i++) { + if (offsets[i] == off) { + ssbo_idx = i; + found = true; + break; + } + } + assert(found); + + nir_def *idx_ssa = nir_imm_int(&b, ssbo_idx); + nir_def *off_ssa = rel ? rel : nir_imm_int(&b, 0); + + switch (kind) { + case OP_LOAD: { + nir_def *result = + nir_load_ssbo(&b, intrin->def.num_components, + intrin->def.bit_size, idx_ssa, off_ssa, + .access = nir_intrinsic_access(intrin), + .align_mul = nir_intrinsic_align_mul(intrin), + .align_offset = nir_intrinsic_align_offset(intrin)); + nir_def_replace(&intrin->def, result); + break; + } + case OP_STORE: + nir_store_ssbo(&b, intrin->src[0].ssa, idx_ssa, off_ssa, + .write_mask = nir_intrinsic_write_mask(intrin), + .access = nir_intrinsic_access(intrin), + .align_mul = nir_intrinsic_align_mul(intrin), + .align_offset = nir_intrinsic_align_offset(intrin)); + nir_instr_remove(instr); + break; + case OP_ATOMIC: { + nir_def *result = + nir_ssbo_atomic(&b, intrin->def.bit_size, idx_ssa, off_ssa, + intrin->src[1].ssa, + .atomic_op = nir_intrinsic_atomic_op(intrin)); + nir_def_replace(&intrin->def, result); + break; + } + case OP_ATOMIC_SWAP: { + nir_def *result = + nir_ssbo_atomic_swap(&b, intrin->def.bit_size, idx_ssa, off_ssa, + intrin->src[1].ssa, intrin->src[2].ssa, + .atomic_op = nir_intrinsic_atomic_op(intrin)); + nir_def_replace(&intrin->def, result); + break; + } + } + } + } + + nir->info.num_ssbos = num_offsets; + nir_progress(true, impl, nir_metadata_none); + return true; +} + static struct crocus_compiled_shader * crocus_compile_cs(struct crocus_context *ice, struct crocus_uncompiled_shader *ish, @@ -2522,6 +2853,9 @@ crocus_compile_cs(struct crocus_context *ice, nir_shader *nir = nir_shader_clone(mem_ctx, ish->nir); + if (devinfo->ver < 8) + NIR_PASS(_, nir, crocus_lower_cs_global_to_ssbo); + NIR_PASS(_, nir, elk_nir_lower_cs_intrinsics, devinfo, cs_prog_data); crocus_setup_uniforms(devinfo, mem_ctx, nir, prog_data, &system_values, @@ -2620,11 +2954,14 @@ crocus_fill_cs_push_const_buffer(struct elk_cs_prog_data *cs_prog_data, uint32_t *dst) { assert(elk_cs_push_const_total_size(cs_prog_data, threads) > 0); - assert(cs_prog_data->push.cross_thread.size == 0); - assert(cs_prog_data->push.per_thread.dwords == 1); - assert(cs_prog_data->base.param[0] == ELK_PARAM_BUILTIN_SUBGROUP_ID); - for (unsigned t = 0; t < threads; t++) - dst[8 * t] = t; + + /* per_thread: subgroup_id -- cross_thread dwords'den sonra yaz */ + if (cs_prog_data->push.per_thread.dwords == 1 && + cs_prog_data->base.param[0] == ELK_PARAM_BUILTIN_SUBGROUP_ID) { + unsigned cross_dwords = cs_prog_data->push.cross_thread.dwords; + for (unsigned t = 0; t < threads; t++) + dst[cross_dwords + 8 * t] = t; + } } /** @@ -2906,6 +3243,9 @@ crocus_create_compute_state(struct pipe_context *ctx, struct crocus_uncompiled_shader *ish = crocus_create_uncompiled_shader(ctx, (void *) state->prog, NULL); + if (ish->nir->info.stage == MESA_SHADER_KERNEL) + ish->nir->info.stage = MESA_SHADER_COMPUTE; + ish->nos |= (1ull << CROCUS_NOS_TEXTURES); // XXX: disallow more than 64KB of shared variables @@ -3112,11 +3452,14 @@ crocus_get_compute_state_info(struct pipe_context *ctx, void *state, struct pipe_compute_state_object_info *info) { struct crocus_screen *screen = (void *) ctx->screen; - info->max_threads = screen->devinfo.max_cs_threads * - screen->devinfo.subslice_total; + const struct intel_device_info *devinfo = &screen->devinfo; + + const uint32_t simd_width = devinfo->ver >= 8 ? 32 : 8; + + info->max_threads = simd_width * devinfo->max_cs_workgroup_threads; info->private_memory = 0; - info->preferred_simd_size = 16; - info->simd_sizes = 8 | 16; + info->preferred_simd_size = simd_width; + info->simd_sizes = devinfo->ver >= 8 ? (8 | 16 | 32) : (8 | 16); } void diff --git a/src/gallium/drivers/crocus/crocus_screen.c b/src/gallium/drivers/crocus/crocus_screen.c index 6c7022a..55adc6d 100644 --- a/src/gallium/drivers/crocus/crocus_screen.c +++ b/src/gallium/drivers/crocus/crocus_screen.c @@ -203,7 +203,12 @@ crocus_init_compute_caps(struct crocus_screen *screen) if (devinfo->ver < 7) return; - const uint32_t max_invocations = 32 * devinfo->max_cs_workgroup_threads; + /* Gen7 (IVB/BYT/HSW) compute dispatch max SIMD width is 8; + * Gfx9+ can reach SIMD32. Using 32 unconditionally overreports + * the work-group size on Gen7 (2048 instead of the real 512). + */ + const uint32_t simd_width = devinfo->ver >= 8 ? 32 : 8; + const uint32_t max_invocations = simd_width * devinfo->max_cs_workgroup_threads; caps->address_bits = 32; @@ -227,6 +232,22 @@ crocus_init_compute_caps(struct crocus_screen *screen) caps->subgroup_sizes = ELK_SUBGROUP_SIZE; caps->max_variable_threads_per_block = max_invocations; + + caps->max_compute_units = intel_device_info_eu_total(devinfo) > 0 + ? intel_device_info_eu_total(devinfo) + : (devinfo->gt == 2 ? 16 : 6); + + /* Gen7 supports up to 2GB (1 << 31) buffers via stateless access. + * Limit to 1GB to be safe with 32-bit addressing. + */ + caps->max_global_size = 1ULL << 30; /* 1 GB */ + caps->max_mem_alloc_size = 1ULL << 29; /* 512 MB — meets CL min for non-CUSTOM */ + + caps->max_clock_frequency = 1300; /* MHz, approximate for IVB GT2 */ + /* Gen7+ has a real, physically separate Shared Local Memory block + * (accessed via Binding Table Index 254), unlike architectures where + * "local" memory is just a region of global memory. */ + caps->has_dedicated_local_mem = true; } static void @@ -289,6 +310,7 @@ crocus_init_screen_caps(struct crocus_screen *screen) caps->gl_clamp = true; caps->legacy_math_rules = true; caps->native_fence_fd = true; + caps->cl_gl_sharing = true; caps->int64 = caps->shader_ballot = @@ -493,63 +515,7 @@ crocus_query_memory_info(struct pipe_screen *pscreen, info->avail_staging_memory = info->total_staging_memory; } -static int -crocus_get_compute_param(struct pipe_screen *pscreen, - enum pipe_shader_ir ir_type, - enum pipe_compute_cap param, - void *ret) -{ - struct crocus_screen *screen = (struct crocus_screen *) pscreen; - const struct intel_device_info *devinfo = &screen->devinfo; - switch (param) { - case PIPE_COMPUTE_CAP_MAX_COMPUTE_UNITS: - if (ret) { - uint32_t num_eu = devinfo->num_eu_total > 0 ? devinfo->num_eu_total : ((devinfo->gt == 2) ? 16 : 6); - ((uint32_t *)ret)[0] = num_eu; - } - return sizeof(uint32_t); - - case PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK: - if (ret) - ((uint64_t *)ret)[0] = 1024; - return sizeof(uint64_t); - - case PIPE_COMPUTE_CAP_MAX_GRID_SIZE: - if (ret) { - ((uint64_t *)ret)[0] = 65535; - ((uint64_t *)ret)[1] = 65535; - ((uint64_t *)ret)[2] = 65535; - } - return 3 * sizeof(uint64_t); - - case PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE: - if (ret) { - ((uint64_t *)ret)[0] = 1024; - ((uint64_t *)ret)[1] = 1024; - ((uint64_t *)ret)[2] = 1024; - } - return 3 * sizeof(uint64_t); - - case PIPE_COMPUTE_CAP_PREFERRED_BLOCK_SIZE: - if (ret) - ((uint64_t *)ret)[0] = 256; - return sizeof(uint64_t); - - case PIPE_COMPUTE_CAP_IMAGES_SUPPORTED: - if (ret) - ((uint32_t *)ret)[0] = 1; - return sizeof(uint32_t); - - case PIPE_COMPUTE_CAP_SUBGROUP_SIZE: - if (ret) - ((uint32_t *)ret)[0] = devinfo->subgroup_size ? devinfo->subgroup_size : 16; - return sizeof(uint32_t); - - default: - return 0; - } -} static struct disk_cache * crocus_get_disk_shader_cache(struct pipe_screen *pscreen) @@ -720,8 +686,6 @@ crocus_screen_create(int fd, const struct pipe_screen_config *config) pscreen->query_memory_info = crocus_query_memory_info; pscreen->get_driver_query_group_info = crocus_get_monitor_group_info; pscreen->get_driver_query_info = crocus_get_monitor_info; - pscreen->get_compute_param = crocus_get_compute_param; - crocus_init_shader_caps(screen); crocus_init_compute_caps(screen); crocus_init_screen_caps(screen); diff --git a/src/gallium/drivers/crocus/crocus_state.c b/src/gallium/drivers/crocus/crocus_state.c index b47d38e..1cdf675 100644 --- a/src/gallium/drivers/crocus/crocus_state.c +++ b/src/gallium/drivers/crocus/crocus_state.c @@ -5513,6 +5513,35 @@ crocus_populate_binding_table(struct crocus_context *ice, s++; } +/* IVB Gen7: emit one surface per global binding using actual BO address. + * handle[] holds relative offset (0), surface base = BO gtt address. + * store_global(val, abs_addr) works because abs_addr = gtt_offset + rel, + * and surface base = gtt_offset, so hw writes to gtt_offset + rel. */ + foreach_surface_used(i, CROCUS_SURFACE_GROUP_GLOBAL) { + struct isl_device *isl_dev_g = &batch->screen->isl_dev; + uint32_t g_offset = 0; + uint32_t *g_surf = stream_state(batch, isl_dev_g->ss.size, + isl_dev_g->ss.align, &g_offset); + struct pipe_resource *global_res = ice->state.global_bindings[i]; + if (global_res) { + struct crocus_resource *gres = (struct crocus_resource *) global_res; + isl_buffer_fill_state(isl_dev_g, g_surf, + .address = crocus_state_reloc(batch, + g_offset + isl_dev_g->ss.addr_offset, + gres->bo, 0, + RELOC_32BIT | RELOC_WRITE), + .size_B = gres->bo->size, + .format = ISL_FORMAT_RAW, + .swizzle = ISL_SWIZZLE_IDENTITY, + .stride_B = 1, + .mocs = crocus_mocs(gres->bo, isl_dev_g)); + } else { + emit_null_surface(batch, &g_offset); + } + surf_offsets[s] = g_offset; + s++; + } + } /* ------------------------------------------------------------------- */ static uint32_t @@ -5544,6 +5573,7 @@ crocus_update_surface_base_address(struct crocus_batch *batch) crocus_emit_cmd(batch, GENX(STATE_BASE_ADDRESS), sba) { /* Set base addresses */ sba.GeneralStateBaseAddressModifyEnable = true; + sba.GeneralStateBaseAddress = ro_bo(batch->state.bo, 0); #if GFX_VER >= 6 sba.DynamicStateBaseAddressModifyEnable = true; @@ -5587,6 +5617,7 @@ crocus_update_surface_base_address(struct crocus_batch *batch) */ sba.DynamicStateAccessUpperBound = ro_bo(NULL, 0xfffff000); sba.DynamicStateAccessUpperBoundModifyEnable = true; + sba.GeneralStateAccessUpperBound = ro_bo(NULL, 0xfffff000); #else /* Same idea but using General State Base Address on Gen4-5 */ sba.GeneralStateAccessUpperBound = ro_bo(NULL, 0xfffff000); @@ -5598,7 +5629,10 @@ crocus_update_surface_base_address(struct crocus_batch *batch) * if you don't set the "Address Modify Enable" bit for the base. */ sba.GeneralStateMOCS = mocs; - sba.StatelessDataPortAccessMOCS = mocs; + sba.StatelessDataPortAccessMOCS = mocs ? mocs : 1; /* Try L3 cacheable if 0 */ +#if GFX_VERx10 == 70 + sba.StatelessDataPortAccessForceWriteThru = true; +#endif sba.DynamicStateMOCS = mocs; sba.IndirectObjectMOCS = mocs; sba.InstructionMOCS = mocs; @@ -8073,8 +8107,15 @@ crocus_upload_compute_state(struct crocus_context *ice, elk_cs_get_dispatch_info(devinfo, cs_prog_data, grid->block); crocus_update_surface_base_address(batch); - if ((stage_dirty & CROCUS_STAGE_DIRTY_CONSTANTS_CS) && shs->sysvals_need_upload) + if ((stage_dirty & CROCUS_STAGE_DIRTY_CONSTANTS_CS) && shs->sysvals_need_upload) { + for (unsigned i = 0; i < CROCUS_MAX_GLOBAL_BINDINGS; i++) { + if (ice->state.global_bindings[i]) { + struct crocus_resource *res = (struct crocus_resource *) ice->state.global_bindings[i]; + crocus_use_bo(batch, res->bo, true); + } + } upload_sysvals(ice, MESA_SHADER_COMPUTE); + } if (stage_dirty & CROCUS_STAGE_DIRTY_BINDINGS_CS) { crocus_populate_binding_table(ice, batch, MESA_SHADER_COMPUTE, false); @@ -8145,13 +8186,10 @@ crocus_upload_compute_state(struct crocus_context *ice, } } - /* TODO: Combine subgroup-id with cbuf0 so we can push regular uniforms */ + /* Push cross_thread (kernel args) + per_thread (subgroup_id) to CURBE */ if ((stage_dirty & CROCUS_STAGE_DIRTY_CS) || cs_prog_data->local_size[0] == 0 /* Variable local group size */) { uint32_t curbe_data_offset = 0; - assert(cs_prog_data->push.cross_thread.dwords == 0 && - cs_prog_data->push.per_thread.dwords == 1 && - cs_prog_data->base.param[0] == ELK_PARAM_BUILTIN_SUBGROUP_ID); const unsigned push_const_size = elk_cs_push_const_total_size(cs_prog_data, dispatch.threads); uint32_t *curbe_data_map = @@ -8160,6 +8198,24 @@ crocus_upload_compute_state(struct crocus_context *ice, &curbe_data_offset); assert(curbe_data_map); memset(curbe_data_map, 0x5a, align(push_const_size, 64)); + + if (cs_prog_data->push.cross_thread.size > 0) { + struct pipe_constant_buffer *cbuf = &shs->constbufs[0]; + if (cbuf->user_buffer) { + memcpy(curbe_data_map, cbuf->user_buffer, + cs_prog_data->push.cross_thread.size); + } else if (cbuf->buffer) { + struct crocus_resource *res = + (struct crocus_resource *) cbuf->buffer; + void *map = crocus_bo_map(NULL, res->bo, MAP_READ); + if (map) { + memcpy(curbe_data_map, + (uint8_t *)map + cbuf->buffer_offset, + cs_prog_data->push.cross_thread.size); + } + } + } + crocus_fill_cs_push_const_buffer(cs_prog_data, dispatch.threads, curbe_data_map); @@ -8184,7 +8240,8 @@ crocus_upload_compute_state(struct crocus_context *ice, idd.ConstantURBEntryReadLength = cs_prog_data->push.per_thread.regs; idd.BarrierEnable = cs_prog_data->uses_barrier; idd.SharedLocalMemorySize = intel_compute_slm_encode_size(GFX_VER, - prog_data->total_shared); + prog_data->total_shared + + grid->variable_shared_mem); #if GFX_VERx10 >= 75 idd.CrossThreadConstantDataReadLength = cs_prog_data->push.cross_thread.regs; #endif @@ -8279,6 +8336,11 @@ crocus_upload_compute_state(struct crocus_context *ice, crocus_emit_cmd(batch, GENX(MEDIA_STATE_FLUSH), msf); + crocus_emit_pipe_control_flush(batch, + "compute: flush DC after GPGPU_WALKER", + PIPE_CONTROL_DATA_CACHE_FLUSH | + PIPE_CONTROL_CS_STALL); + batch->contains_draw = true; } @@ -8286,23 +8348,40 @@ static void crocus_set_global_binding(struct pipe_context *ctx, unsigned start_slot, unsigned count, struct pipe_resource **resources, - uint32_t **handles) -{ + uint32_t **handles) { struct crocus_context *ice = (struct crocus_context *) ctx; assert(start_slot + count <= CROCUS_MAX_GLOBAL_BINDINGS); + for (unsigned i = 0; i < count; i++) { if (resources && resources[i]) { - pipe_resource_reference(&ice->state.global_bindings[start_slot + i], - resources[i]); - struct crocus_resource *res = (struct crocus_resource *) resources[i]; - assert(res->base.b.target == PIPE_BUFFER); - uint32_t addr = 0; - memcpy(&addr, handles[i], sizeof(addr)); - addr += res->bo->gtt_offset; - memcpy(handles[i], &addr, sizeof(addr)); + pipe_resource_reference(&ice->state.global_bindings[start_slot + i], + resources[i]); + struct crocus_resource *res = (struct crocus_resource *) resources[i]; + assert(res->base.b.target == PIPE_BUFFER); + /* IVB: handle = 0 (offset from BO base = 0). + * Surface base = BO real address via reloc. + * store_global(val, 0 + i*4) -> surface[base=real_addr][offset=i*4] */ + + uint32_t addr = 0; + memcpy(handles[i], &addr, sizeof(addr)); + ice->state.global_binding_handles[start_slot + i] = NULL; + + /* IVB: also bind as SSBO at the same index, for the load_global -> + * load_ssbo NIR redirect pass (crocus_lower_cs_global_to_ssbo). */ + struct crocus_shader_state *cs_shs = + &ice->state.shaders[MESA_SHADER_COMPUTE]; + struct pipe_shader_buffer *ssbo = &cs_shs->ssbo[start_slot + i]; + pipe_resource_reference(&ssbo->buffer, &res->base.b); + ssbo->buffer_offset = res->offset; + ssbo->buffer_size = res->bo->size - res->offset; + cs_shs->bound_ssbos |= 1u << (start_slot + i); + cs_shs->writable_ssbos |= 1u << (start_slot + i); + res->bind_history |= PIPE_BIND_SHADER_BUFFER; + res->bind_stages |= 1u << MESA_SHADER_COMPUTE; } else { pipe_resource_reference(&ice->state.global_bindings[start_slot + i], NULL); + ice->state.global_binding_handles[start_slot + i] = NULL; } } ice->state.stage_dirty |= CROCUS_STAGE_DIRTY_BINDINGS_CS; diff --git a/src/gallium/frontends/rusticl/api/context.rs b/src/gallium/frontends/rusticl/api/context.rs index 1f1db47..85c0f9f 100644 --- a/src/gallium/frontends/rusticl/api/context.rs +++ b/src/gallium/frontends/rusticl/api/context.rs @@ -20,6 +20,14 @@ use std::ffi::c_void; use std::ptr; use std::slice; +fn rusticl_dbg(msg: &str) { + use std::io::Write; + if let Ok(mut f) = std::fs::OpenOptions::new().create(true).append(true).open("/tmp/rusticl_debug.log") { + let _ = writeln!(f, "{}", msg); + let _ = f.flush(); + } +} + #[cl_info_entrypoint(clGetContextInfo)] unsafe impl CLInfo for cl_context { fn query(&self, q: cl_context_info, v: CLInfoValue) -> CLResult { @@ -99,7 +107,9 @@ pub fn get_gl_context_info_khr( } } + rusticl_dbg(&format!("RUSTICL_DBG: gl_context={:?} glx_display={:?} egl_display={:?}", gl_context, glx_display, egl_display)); let gl_ctx_manager = GLCtxManager::new(gl_context, glx_display, egl_display)?; + rusticl_dbg(&format!("RUSTICL_DBG: GLCtxManager::new result is_some={}", gl_ctx_manager.is_some())); unsafe { gl_ctx_manager .ok_or(CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR)? @@ -175,28 +185,24 @@ fn create_context( let gl_ctx_manager = GLCtxManager::new(gl_context, glx_display, egl_display)?; if let Some(gl_ctx_manager) = &gl_ctx_manager { - // errcode_ret returns CL_INVALID_OPERATION if a context was specified as described above - // and any of the following conditions hold: - // ... - // Any of the devices specified in the devices argument cannot support OpenCL objects which - // share the data store of an OpenGL object. - let [dev] = devs.as_slice() else { + rusticl_dbg(&format!("RUSTICL_DBG: create_context fail at (B) - multiple devices with gl sharing")); return Err(CL_INVALID_OPERATION); }; if !dev.is_gl_sharing_supported() { + rusticl_dbg(&format!("RUSTICL_DBG: create_context fail at (C) - gl sharing not supported on this device")); return Err(CL_INVALID_OPERATION); } - // gl sharing is only supported on devices with an UUID, so we can simply unwrap it let dev_uuid: [c_char; UUID_SIZE] = dev .screen() .device_uuid() .unwrap_or_default() .map(|val| val as c_char); if gl_ctx_manager.interop_dev_info.device_uuid != dev_uuid { - // we only support gl_sharing on the same device + eprintln!("RUSTICL_DBG: create_context fail at (D) - uuid mismatch: gl_ctx={:?} dev={:?}", + gl_ctx_manager.interop_dev_info.device_uuid, dev_uuid); return Err(CL_INVALID_OPERATION); } } diff --git a/src/gallium/frontends/rusticl/api/device.rs b/src/gallium/frontends/rusticl/api/device.rs index d25dad9..9dde388 100644 --- a/src/gallium/frontends/rusticl/api/device.rs +++ b/src/gallium/frontends/rusticl/api/device.rs @@ -165,8 +165,14 @@ unsafe impl CLInfo for cl_device_id { } CL_DEVICE_LINKER_AVAILABLE => v.write::(true), CL_DEVICE_LOCAL_MEM_SIZE => v.write::(dev.local_mem_size()), - // TODO add query for CL_LOCAL vs CL_GLOBAL - CL_DEVICE_LOCAL_MEM_TYPE => v.write::(CL_GLOBAL), + CL_DEVICE_LOCAL_MEM_TYPE => { + let local_type = if dev.screen().compute_caps().has_dedicated_local_mem { + CL_LOCAL + } else { + CL_GLOBAL + }; + v.write::(local_type) + } CL_DEVICE_LUID => v.write::<[cl_uchar; CL_LUID_SIZE as usize]>( dev.screen().device_luid().unwrap_or_default(), ), diff --git a/src/gallium/frontends/rusticl/api/memory.rs b/src/gallium/frontends/rusticl/api/memory.rs index 8960db4..be71b25 100644 --- a/src/gallium/frontends/rusticl/api/memory.rs +++ b/src/gallium/frontends/rusticl/api/memory.rs @@ -916,6 +916,23 @@ fn create_image_with_properties( )?; let filtered_flags = filter_image_access_flags(flags); + { + use std::io::Write; + if let Ok(mut dbgf) = std::fs::OpenOptions::new().create(true).append(true).open("/tmp/rusticl_debug.log") { + let img_fmt = unsafe { *image_format }; + let _ = writeln!(dbgf, "RUSTICL_DBG: create_image format={:?} channel_order={} channel_data_type={} image_type={} filtered_flags={:#x}", + format, img_fmt.image_channel_order, img_fmt.image_channel_data_type, desc.image_type, filtered_flags); + for d in &c.devs { + match d.formats.get(format) { + None => { let _ = writeln!(dbgf, "RUSTICL_DBG: device has NO entry for this pipe_format at all"); } + Some(f) => { + let _ = writeln!(dbgf, "RUSTICL_DBG: device format map: {:?}", f); + } + } + } + let _ = dbgf.flush(); + } + } // CL_IMAGE_FORMAT_NOT_SUPPORTED if there are no devices in context that support image_format. c.devs .iter() diff --git a/src/gallium/frontends/rusticl/core/device.rs b/src/gallium/frontends/rusticl/core/device.rs index 551497e..056130a 100644 --- a/src/gallium/frontends/rusticl/core/device.rs +++ b/src/gallium/frontends/rusticl/core/device.rs @@ -935,12 +935,21 @@ impl DeviceBase { } pub fn is_gl_sharing_supported(&self) -> bool { - self.screen.caps().cl_gl_sharing - && self.screen.caps().dmabuf != 0 - && !self.is_device_software() - && self.screen.is_res_handle_supported() - && self.screen.device_uuid().is_some() - && self.caps.has_create_fence_fd + let c1 = self.screen.caps().cl_gl_sharing; + let c2 = self.screen.caps().dmabuf != 0; + let c3 = !self.is_device_software(); + let c4 = self.screen.is_res_handle_supported(); + let c5 = self.screen.device_uuid().is_some(); + let c6 = self.caps.has_create_fence_fd; + { + use std::io::Write; + if let Ok(mut f) = std::fs::OpenOptions::new().create(true).append(true).open("/tmp/rusticl_debug.log") { + let _ = writeln!(f, "RUSTICL_DBG: is_gl_sharing_supported: cl_gl_sharing={} dmabuf={} !is_sw={} res_handle={} uuid_some={} fence_fd={}", + c1, c2, c3, c4, c5, c6); + let _ = f.flush(); + } + } + c1 && c2 && c3 && c4 && c5 && c6 } pub fn is_device_software(&self) -> bool { diff --git a/src/gallium/frontends/rusticl/core/kernel.rs b/src/gallium/frontends/rusticl/core/kernel.rs index e608a8d..7365a30 100644 --- a/src/gallium/frontends/rusticl/core/kernel.rs +++ b/src/gallium/frontends/rusticl/core/kernel.rs @@ -1801,6 +1801,9 @@ impl Kernel { // subtract the shader local_size as we only request something on top of that. variable_local_size -= static_local_size; + let input_ptr_before = exec_builder.input().as_ptr(); + let input_len_before = exec_builder.input().len(); + let (resources, mut globals) = exec_builder.get_resources_and_globals(); ctx.bind_kernel(&nir_kernel_builds, variant)?; diff --git a/src/gallium/frontends/rusticl/core/queue.rs b/src/gallium/frontends/rusticl/core/queue.rs index 893a13e..4ee692f 100644 --- a/src/gallium/frontends/rusticl/core/queue.rs +++ b/src/gallium/frontends/rusticl/core/queue.rs @@ -168,6 +168,7 @@ impl<'c> QueueContextWithState<'c> { pub fn update_cb0(&self, data: &[u8]) -> CLResult<()> { // only update if we actually bind data if !data.is_empty() { + eprintln!("update_cb0: use_stream={} len={}", self.use_stream, data.len()); if self.use_stream { if !self.ctx.set_constant_buffer_stream(0, data) { return Err(CL_OUT_OF_RESOURCES); diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index 8854309..bc8d505 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -825,6 +825,7 @@ struct pipe_compute_caps { unsigned max_variable_threads_per_block; uint64_t max_mem_alloc_size; uint64_t max_global_size; + bool has_dedicated_local_mem; /* true if SLM is physically separate from global memory */ }; struct pipe_mesh_caps { diff --git a/src/intel/compiler/elk/elk_compiler.c b/src/intel/compiler/elk/elk_compiler.c index 17b250b..92d8c2c 100644 --- a/src/intel/compiler/elk/elk_compiler.c +++ b/src/intel/compiler/elk/elk_compiler.c @@ -172,6 +172,10 @@ elk_get_compiler_config_value(const struct elk_compiler *compiler) unsigned elk_prog_data_size(mesa_shader_stage stage) { + if (stage == MESA_SHADER_KERNEL) { + stage = MESA_SHADER_COMPUTE; + } + static const size_t stage_sizes[] = { [MESA_SHADER_VERTEX] = sizeof(struct elk_vs_prog_data), [MESA_SHADER_TESS_CTRL] = sizeof(struct elk_tcs_prog_data), diff --git a/src/intel/compiler/elk/elk_compiler.h b/src/intel/compiler/elk/elk_compiler.h index a8c75a4..6f9f9fe 100644 --- a/src/intel/compiler/elk/elk_compiler.h +++ b/src/intel/compiler/elk/elk_compiler.h @@ -1053,6 +1053,7 @@ struct elk_cs_prog_data { * surface indices the CS-specific surfaces */ uint32_t work_groups_start; + uint32_t global_start; /* IVB: BTI for full-GTT global surface */ /** @} */ } binding_table; }; diff --git a/src/intel/compiler/elk/elk_fs_nir.cpp b/src/intel/compiler/elk/elk_fs_nir.cpp index 474cd76..74b9ea1 100644 --- a/src/intel/compiler/elk/elk_fs_nir.cpp +++ b/src/intel/compiler/elk/elk_fs_nir.cpp @@ -5114,6 +5114,31 @@ fs_nir_emit_intrinsic(nir_to_elk_state &ntb, case nir_intrinsic_load_global: case nir_intrinsic_load_global_constant: { + if (devinfo->ver < 8) { + elk_fs_reg dest = get_nir_def(ntb, instr->def); + const unsigned bit_size = instr->def.bit_size; + elk_fs_reg srcs[SURFACE_LOGICAL_NUM_SRCS]; + /* IVB: use dedicated full-GTT surface for global access */ + const struct elk_cs_prog_data *cs_pd = + elk_cs_prog_data(ntb.s.prog_data); + srcs[SURFACE_LOGICAL_SRC_SURFACE] = elk_imm_ud(cs_pd->binding_table.global_start); + srcs[SURFACE_LOGICAL_SRC_ADDRESS] = get_nir_src(ntb, instr->src[0]); + srcs[SURFACE_LOGICAL_SRC_IMM_DIMS] = elk_imm_ud(1); + srcs[SURFACE_LOGICAL_SRC_ALLOW_SAMPLE_MASK] = elk_imm_ud(0); + dest.type = elk_reg_type_from_bit_size(bit_size, ELK_REGISTER_TYPE_UD); + + if (bit_size == 32 && nir_intrinsic_align(instr) >= 4) { + srcs[SURFACE_LOGICAL_SRC_IMM_ARG] = elk_imm_ud(instr->num_components); + elk_fs_inst *inst = bld.emit(ELK_SHADER_OPCODE_UNTYPED_SURFACE_READ_LOGICAL, dest, srcs, SURFACE_LOGICAL_NUM_SRCS); + inst->size_written = instr->num_components * s.dispatch_width * 4; + } else { + srcs[SURFACE_LOGICAL_SRC_IMM_ARG] = elk_imm_ud(bit_size); + elk_fs_reg read_result = bld.vgrf(ELK_REGISTER_TYPE_UD); + bld.emit(ELK_SHADER_OPCODE_BYTE_SCATTERED_READ_LOGICAL, read_result, srcs, SURFACE_LOGICAL_NUM_SRCS); + bld.MOV(dest, subscript(read_result, dest.type, 0)); + } + break; + } assert(devinfo->ver >= 8); assert(instr->def.bit_size <= 32); @@ -5150,13 +5175,34 @@ fs_nir_emit_intrinsic(nir_to_elk_state &ntb, } case nir_intrinsic_store_global: { + if (devinfo->ver < 8) { + const unsigned bit_size = nir_src_bit_size(instr->src[0]); + elk_fs_reg srcs[SURFACE_LOGICAL_NUM_SRCS]; + /* IVB: use dedicated full-GTT surface for global access */ + const struct elk_cs_prog_data *cs_pd = + elk_cs_prog_data(ntb.s.prog_data); + srcs[SURFACE_LOGICAL_SRC_SURFACE] = elk_imm_ud(cs_pd->binding_table.global_start); + srcs[SURFACE_LOGICAL_SRC_ADDRESS] = get_nir_src(ntb, instr->src[1]); + srcs[SURFACE_LOGICAL_SRC_IMM_DIMS] = elk_imm_ud(1); + srcs[SURFACE_LOGICAL_SRC_ALLOW_SAMPLE_MASK] = elk_imm_ud(1); + + elk_fs_reg data = get_nir_src(ntb, instr->src[0]); + data.type = elk_reg_type_from_bit_size(bit_size, ELK_REGISTER_TYPE_UD); + + if (bit_size == 32 && nir_intrinsic_align(instr) >= 4) { + srcs[SURFACE_LOGICAL_SRC_DATA] = data; + srcs[SURFACE_LOGICAL_SRC_IMM_ARG] = elk_imm_ud(instr->num_components); + bld.emit(ELK_SHADER_OPCODE_UNTYPED_SURFACE_WRITE_LOGICAL, elk_fs_reg(), srcs, SURFACE_LOGICAL_NUM_SRCS); + } else { + srcs[SURFACE_LOGICAL_SRC_IMM_ARG] = elk_imm_ud(bit_size); + srcs[SURFACE_LOGICAL_SRC_DATA] = bld.vgrf(ELK_REGISTER_TYPE_UD); + bld.MOV(srcs[SURFACE_LOGICAL_SRC_DATA], data); + bld.emit(ELK_SHADER_OPCODE_BYTE_SCATTERED_WRITE_LOGICAL, elk_fs_reg(), srcs, SURFACE_LOGICAL_NUM_SRCS); + } + break; + } assert(devinfo->ver >= 8); - - assert(nir_src_bit_size(instr->src[0]) <= 32); - assert(nir_intrinsic_write_mask(instr) == - (1u << instr->num_components) - 1); - assert(nir_intrinsic_align(instr) > 0); - + elk_fs_reg srcs[A64_LOGICAL_NUM_SRCS]; srcs[A64_LOGICAL_ADDRESS] = get_nir_src(ntb, instr->src[1]); srcs[A64_LOGICAL_ENABLE_HELPERS] = @@ -5523,6 +5569,7 @@ fs_nir_emit_intrinsic(nir_to_elk_state &ntb, srcs[SURFACE_LOGICAL_SRC_SURFACE] = elk_imm_ud(GFX8_BTI_STATELESS_NON_COHERENT); } else { + /* IVB: use dedicated full-GTT surface instead of stateless BTI 255 */ srcs[SURFACE_LOGICAL_SRC_SURFACE] = elk_imm_ud(ELK_BTI_STATELESS); } @@ -6241,6 +6288,7 @@ static void fs_nir_emit_global_atomic(nir_to_elk_state &ntb, const fs_builder &bld, nir_intrinsic_instr *instr) { + const intel_device_info *devinfo = ntb.devinfo; enum elk_lsc_opcode op = elk_lsc_aop_for_nir_intrinsic(instr); int num_data = lsc_op_num_data_values(op); @@ -6262,6 +6310,20 @@ fs_nir_emit_global_atomic(nir_to_elk_state &ntb, const fs_builder &bld, data = tmp; } + if (devinfo->ver < 8) { + elk_fs_reg srcs[SURFACE_LOGICAL_NUM_SRCS]; + srcs[SURFACE_LOGICAL_SRC_SURFACE] = elk_imm_ud(ELK_BTI_STATELESS); + srcs[SURFACE_LOGICAL_SRC_ADDRESS] = addr; + srcs[SURFACE_LOGICAL_SRC_IMM_DIMS] = elk_imm_ud(1); + srcs[SURFACE_LOGICAL_SRC_ALLOW_SAMPLE_MASK] = elk_imm_ud(1); + if (num_data >= 1) + srcs[SURFACE_LOGICAL_SRC_DATA] = data; + srcs[SURFACE_LOGICAL_SRC_IMM_ARG] = elk_imm_ud(op); + + bld.emit(ELK_SHADER_OPCODE_UNTYPED_ATOMIC_LOGICAL, dest, srcs, SURFACE_LOGICAL_NUM_SRCS); + return; + } + elk_fs_reg srcs[A64_LOGICAL_NUM_SRCS]; srcs[A64_LOGICAL_ADDRESS] = addr; srcs[A64_LOGICAL_SRC] = data; @@ -6853,6 +6915,7 @@ fs_nir_emit_instr(nir_to_elk_state &ntb, nir_instr *instr) fs_nir_emit_fs_intrinsic(ntb, nir_instr_as_intrinsic(instr)); break; case MESA_SHADER_COMPUTE: + case MESA_SHADER_KERNEL: fs_nir_emit_cs_intrinsic(ntb, nir_instr_as_intrinsic(instr)); break; default: diff --git a/src/intel/compiler/elk/elk_lower_logical_sends.cpp b/src/intel/compiler/elk/elk_lower_logical_sends.cpp index 368c234..59b2d3b 100644 --- a/src/intel/compiler/elk/elk_lower_logical_sends.cpp +++ b/src/intel/compiler/elk/elk_lower_logical_sends.cpp @@ -1199,8 +1199,7 @@ lower_surface_logical_send(const fs_builder &bld, elk_fs_inst *inst) if (is_typed_access || is_stateless) { fs_builder ubld = bld.exec_all().group(8, 0); header = ubld.vgrf(ELK_REGISTER_TYPE_UD); - if (is_stateless) { - assert(!is_surface_access); + if (is_stateless && !is_surface_access) { ubld.emit(ELK_SHADER_OPCODE_SCRATCH_HEADER, header); } else { ubld.MOV(header, elk_imm_d(0)); diff --git a/src/intel/compiler/elk/elk_nir.c b/src/intel/compiler/elk/elk_nir.c index bfed62b..cef363b 100644 --- a/src/intel/compiler/elk/elk_nir.c +++ b/src/intel/compiler/elk/elk_nir.c @@ -766,9 +766,12 @@ elk_nir_optimize(nir_shader *nir, bool is_scalar, OPT(nir_remove_dead_variables, nir_var_function_temp, NULL); } -static unsigned -lower_bit_size_callback(const nir_instr *instr, UNUSED void *data) +static unsigned +lower_bit_size_callback(const nir_instr *instr, void *data) { + const struct elk_compiler *compiler = data; + const struct intel_device_info *devinfo = compiler->devinfo; + switch (instr->type) { case nir_instr_type_alu: { nir_alu_instr *alu = nir_instr_as_alu(instr); @@ -785,9 +788,19 @@ lower_bit_size_callback(const nir_instr *instr, UNUSED void *data) default: break; } - - if (alu->def.bit_size >= 32) - return 0; + if (alu->def.bit_size == 16 && + devinfo->ver < 8 && + nir_op_infos[alu->op].output_type == nir_type_float) { + /* Gen7 has no native FP16 ALU/register support at all (see the + * empty HF entry in gfx7_hw_3src_type[] / gfx7_hw_type[] in + * elk_reg_type.c) -- unlike >=Gfx8, it cannot represent a + * 16-bit float operand or result under ANY circumstance, not + * just when inputs are mixed-width. Lower unconditionally, + * regardless of the source bit sizes, or elk_reg_type_to_hw_type() + * will hit an unencodable HF register type and assert. + */ + return 32; + } /* Note: nir_op_iabs and nir_op_ineg are not lowered here because the * 8-bit ABS or NEG instruction should eventually get copy propagated @@ -805,7 +818,7 @@ lower_bit_size_callback(const nir_instr *instr, UNUSED void *data) case nir_op_ffract: case nir_op_fround_even: case nir_op_ftrunc: - return 32; + return alu->def.bit_size < 32 ? 32 : 0; case nir_op_frcp: case nir_op_frsq: case nir_op_fsqrt: @@ -814,7 +827,13 @@ lower_bit_size_callback(const nir_instr *instr, UNUSED void *data) case nir_op_flog2: case nir_op_fsin: case nir_op_fcos: - return 32; + /* Same issue as the idiv/umod/fceil group above: these + * transcendental ops need >=32-bit precision on Gen7, but if + * the source is already >=32-bit, unconditionally returning + * 32 here trips the nir_lower_bit_size assert (src->bit_size + * < bit_size fails when equal or the source is 64-bit). + */ + return alu->def.bit_size < 32 ? 32 : 0; case nir_op_isign: UNREACHABLE("Should have been lowered by nir_opt_algebraic."); default: @@ -1310,8 +1329,26 @@ get_mem_access_size_align(nir_intrinsic_op intrin, uint8_t bytes, bool offset_is_const, enum gl_access_qualifier access, const void *cb_data) { + const struct intel_device_info *devinfo = cb_data; const uint32_t align = nir_combined_align(align_mul, align_offset); + /* IVB (Gen7, verx10=70) has no byte-scattered dataport message -- + * elk_dp_byte_scattered_rw_desc() asserts verx10 >= 75 (Haswell+). + * This is a real HW limitation, not a missing BTI like the global + * stateless case. Never request a sub-dword access on this hardware; + * always request dword granularity. nir_lower_mem_access_bit_sizes + * turns the mismatch into a shift+extract on the load side, and an + * atomic iand/ior read-modify-write on the store side (both already + * generic in the pass, we just need to ask for them). */ + if (devinfo->verx10 < 75 && (align < 4 || bytes < 4)) { + return (nir_mem_access_size_align) { + .bit_size = 32, + .num_components = 1, + .align = 4, + .shift = nir_mem_access_shift_method_scalar, + }; + } + switch (intrin) { case nir_intrinsic_load_ssbo: case nir_intrinsic_load_shared: @@ -1401,6 +1438,7 @@ elk_vectorize_lower_mem_access(nir_shader *nir, OPT(nir_opt_load_store_vectorize, &options); } + const struct intel_device_info *devinfo = compiler->devinfo; nir_lower_mem_access_bit_sizes_options mem_access_options = { .modes = nir_var_mem_ssbo | nir_var_mem_constant | @@ -1409,6 +1447,8 @@ elk_vectorize_lower_mem_access(nir_shader *nir, nir_var_mem_global | nir_var_mem_shared, .callback = get_mem_access_size_align, + .cb_data = devinfo, + .may_lower_unaligned_stores_to_atomics = devinfo->verx10 < 75, }; OPT(nir_lower_mem_access_bit_sizes, &mem_access_options); diff --git a/src/intel/compiler/elk/elk_reg_type.c b/src/intel/compiler/elk/elk_reg_type.c index c484c5d..be68c91 100644 --- a/src/intel/compiler/elk/elk_reg_type.c +++ b/src/intel/compiler/elk/elk_reg_type.c @@ -220,10 +220,16 @@ elk_reg_type_to_hw_type(const struct intel_device_info *devinfo, } if (file == ELK_IMMEDIATE_VALUE) { - assert(table[type].imm_type != (enum hw_imm_type)INVALID); + if (table[type].imm_type == (enum hw_imm_type)INVALID) { + fprintf(stderr, "elk_reg_type_to_hw_type: INVALID imm_type! type=%d\n", type); + assert(0); + } return table[type].imm_type; } else { - assert(table[type].reg_type != (enum hw_reg_type)INVALID); + if (table[type].reg_type == (enum hw_reg_type)INVALID) { + fprintf(stderr, "elk_reg_type_to_hw_type: INVALID reg_type! type=%d\n", type); + assert(0); + } return table[type].reg_type; } } diff --git a/src/intel/dev/__pycache__/intel_device_info.cpython-313.pyc b/src/intel/dev/__pycache__/intel_device_info.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..24513ef83dd38303b9969c0d65f68202e3b2f54b GIT binary patch literal 19913 zcmb7r33wbwc3uzWzyKr;UIKWcNs1ys;vjg5mq_9UL;wWQ00|1DT8)_o(Bd4}?iqlX zm9%mkD^je@a-AsVCQhu_PD15WZst}J$63d53>fq-)Ltj6I2RKqX)d*vbK3u_>gt*4 z2D9GzID_iHUcGwt-m6!ys+v!0YN{oCrhj_>>%TD~Nxw-C;#2Dup5EUiNgqgxq=c?W zFNe&KEOkg`#WBeYH%bR2rDB()gilp)YBR#H2(YM!MHvWp&x)sIWUCM4{&)JHxkg^xwefT!vE91K#-vjs_ z#P@l858?X)zK8K`#)F#eJQeHCD;G-YUcytc?xJ$3r0z1FSe?>^zPs`5!M7LRK79MfLM6J3W84F` zD)Bq03@I-wSI&mrr(r<_Yq?$my^_90m~^AJLMUGqwnEDahK~t^JzWz|9iFd&3-vnA z`cae#!JR#iD3grub}tm4c{& zA9G*&GOX~1^5)ryhr9*kD`&&*^V`agDAUZ+f55YJDfN%Cx@<+->QLB8-M^UTX3m{()AU_d6{-}@d zAM-tb;Cue#zUQCxJ>T~|f5Z3uCw$L;()avR0SW&Uv&f&`z#_HEPY0+!3?P3dfc%WF z&z}uY{9FL}v%WTeEl(7`6~hBuLh8h1IS+sAb;JR z9e=~qcX4*qDt}Y?TP6NptNd+do4@1H7U#l4(xCjaGWwr~wf=cY6nLoo0+4@Ef+)&2m0v6wi=zBX<(JBy z|CRE~Xv1U0zxMk5m9sH-wm(!>*a%m>y5i^+ymN2t&k_e2Pk8%sO2T1eX-@hmG};oiBN;8N+tEcWmDlacL^hqqnC@k0bQ2Ev;{F ze7|aa$FBFQ*Bkb|zxg}yny+nsZ}Yv0UyJX03IeGm%tS1aI1coqO5#o<2KQ=JO=pw& z6qPrt>X-6b%B`tW)mg)|aw!-tlSOr&(< z;&xSECZE1eCVcz?S{IIJsZ@5!l3jDc+cHVn(sMZ@Gbd+fWgX-)Gr2XI@LUEh$&r}L zT}I*e=W=W zccJisG%3-n^M9Uq2NhyswuG3-7B%HUk*8QW6E3r*R4@h|1C_NIKk(kVZC_h{Z+Ru& z$mD>INHfK;7M0Kv8O5h1Zf+-n9rW`Y{m=&8Y@{DjgL#mCcG3??U*d?Q2a|rtFDzX>rsfO@{k*)cx# z?P|j^G6-dvgwA}#tfAVtemAF^87*a!2zCuy3e@hK>S)(UA6&IKOOK-7Y$Kx3qD5W% zXJ-w0gEujuG0Do{M}+U^8sCk)zvkq8fANa8ITlI&&TZ;VL*$3Bt_QJR7k3Ff9wl+GOrJeiVukluZNAX?X*>~{6?r#|H z*W63~YMjSgtOq10pI9XKXiKQy+(wXZ#?VAD>4%)y3*7@>RBVbi^Jzkr8&4B*tBpf9 zg7*fw!HAxo(ap!*XjbU|A*V}jUYFCXJwyZUu)@@M~5&!|XzkhT?PdScilYYp47Wopz*0J?tC)dwjT;I9( zi)eLpFLxQDDsvfHGU)S^5`>`3D2S^_B6(De*)fF~_wg8r3orhVjv`zmK@n7Zs7&9d zv-l~GsHM5(bVM{5FLf&yEX^m2lx`HF#h-md6f#@z=%xd9CHEVP#TXWM%yy~{mxPy# z04x#`rY~9Y>$oyJv(q|l(VP@vr7R(QMmVT2i97SSjg5Prs_BPx?uCJ_?<0eA!vIyb z#O%sE^4v3O&W=-|^Ry_PI4(-3PqI?RGUhUR(hh^njwFy5+mV@UHf8S`8lC7HR(t!d z5B2n^BVAK0(yGePD}9eIqZ7L!K%fkRRC!D~-k`ZM+06+G^&{F{BaLJ)n~~>c?{;?D z`vbiCCKYw8Z(J3v9#ckP?+MV24NXDHu_0^>3biGCdk2o&wJg_H7gAboHfyHsZM^l^ zaMwit)$tK^pnvMbWAb^VOq2}=2!_s{K4ow9wHg|}62JydP6aS!v^#(eT@Pa2Hzxvg zgUXEn*4-P#dIqlt=#(qN0jzr}*vFObAl<+QW9#V;(hc-P__JZvU;ynJXASUY!>Yl6a)w8P%IO{%2+)l|1iu5{fbskik6tGMHbTej z-FzA$HfGIb6-lyXVK3}vXnmx&=p6zJ7q1{g(^K+{mbinxlWg&Gg@nx7@U2~|oXN^q zaWfWXB{FJ}fG_JgSb^3%J1&@uo=djkYC5eg&<S*uw=*K%?~OU%JFlB?_QK_ftURNWUnb$jdZu);!Ns9~FXchkD&OdqkIJ2L)|8LS zOWHCHfj9@d(n@HVY(7_LbPH?)E_Qoz_f^Z@N?AKL?dU`m)R(VjQp>WHUs%YRIdpDh zn4M+DHMCqw zm+dVTd;`Q{bPO!+b{>NRvE2#nHSB8Sa;mYQqDostTIGvVEap+z!$8b@rY&crbwn;R zxkRTf$i?KLF&S+wS`~5>5!3J!Xa~!V?yV*M=m)|Kwd&vkwU?C3+QUO<^C{*IWOvP^ zsH*Xm$EOo6#+ z8kjt@W;V?hqI@Q0+zE8IkT4M4I8)Vd$&+T<)l$1Wl(YEiPE5&@wG`&K!jfJwmovMVACkPuY+5ri zh4@&{5L|sWYgZCFlec&Q_O;`L%;qx*yN0#E2Y0R*vbRw!M!A6Fds=~s(yk|P#>kykttF#SK$x#2B$Z0=!a^!z*Aa61 zB&gKcR94H`dwqbqXlQC$1Iq>UKtJfFjXM{+4^ zCe?I4#i^}jE0;|f346O6Lm{}4PGYBc0=FUdRzx_8muezmK@|&#X}sMmG(lkDXZ+4( z=5^Vam3w*=3MF)xM6~jvVdij&A#2Gbh48Z64=$|HaS`%Lzpo@Tb5U+-BzI|D{szfi16+9CQ<;JKywS+4sMdA=CuWbYdvS+LS?Q5 zC^-`1dM1Eo$})dUWfNLTrG=Z@5z9C;aayXheh3s^C99)bB-ou6dKJfKvp5&K%SB3SNdy6) zd2>!@2@4yz5T5CDKe10_apeX&;pP_p<7O56|-rQJf82~ci6g;D3>4G@yHNjWt)W28+LGw_av zYo<(6O9t1+VmHNAm*)v|34uo0M4t3OnU=@MT~xefbS6LNR|Q*2HH;6ppK{XFmXLMO z#)EGWWM(8+Gkn>lksXt10Hhx_06DRoNa=xqj@2j|vy7uv8agp(z#`v#)vvb;b|DFZ5#YC&5@ zv}8yv#Ip6>`TAl_|H; zUX*Df2)Z$a{5cH>#+e-NhCMN7{9L(uh*IZi0~=a#4Aig>4Y9i@ABUfj=oSqiz37@r zG>g_GMZgFX^SXs@>F6Gl7+Im02x+NAoc$5E;k-p7#naOYFEHp+P}1xi z6V|(6ms3+y=VW9Ie5~*SSc03DIU0}dG(rQx1uJ!KnZ(Bd2i{RZGGXOsn2>%Qkt63b z25gSyjq+2GLFz0HVlhHYA-2WArm}OOPq~s%=8qs2;0t{t(&%^f1mZs1b>bq!6{214 zCv_uc&Kh%hxFGtr*mi;2fn~D1LqA`P2}kdlIlWc3aCn0_$Gtv6->zMoUAJeuE^;uxtYGB!Md_YJfxzWRGm_c5 zrQNP!WUgkcLicFVs|3i_E**IWZ!b5C*$fTCc;v76i~LOP869q+{ik;)W;d`A3r>`$ zaG46f^Mi*kTG6C%yDoF_fG+$R@KnQG2$HbN40e4jf_B;Hr*9)zA&V6H^79i8#2w$& z;0D1Dg5lr5go?vCb~i%zE!3lOWwIT+7TOx99l-9J{wPL((qdtC?SaLzeueanQ za_`V}b^Pk&XsxMWOH$J}D>4VyBz=d16>{Gi8pDfgQ8J9k9x^ zAU+KMoLqYhl-fEP3Hq7bP~ccNEDesdb492XF@sotHH7 z=$N0A(&~It6!!8)*qD3nA@oZ0TZ2N`@ze=*1{s89*HX+_^p>Z>UJ)&>>o}FYD=VeR zv1Qj0d9Jve6?O~yLF}0}rp8;0ZjdN)?`4NOetIU%T#>v6Kc6_P!IFqhmiF^_ zF~w(I_&H7=@m3`=0|?IoJpvjIOes)|(FWHiMli=2Q+jd8fg7)K`d*w$Q<{ohihNb1 zk#4r{W{=`y@9Y z$Vypm1CJ0{`j`?N*94N5vb;N}AQ9fNmdgXPcPWrBXR+sK7F)!{K$OA>RnEWx+Ow2p zwVVqqjcxKU_F8g&p+sK3lb{`%*m%jsWoLq?*76wa2=g59tD#Mvv~Xy}lSETLOegSo z$YvlGtXaDHv5bvka9KL(XDEB|3kMpMG8cVF>BUaR=XPx@R6?I>(LGyP4=fyG)5-FC zBuXTX(DD)aARe)}ZKIYh$`;)PE6L|-$=v%zU!Nncd-vdYoDMb0CrjCw1M+qy*cqR2 z0HoiHMVTkE0(WdI7ajfFn5S&4 zyjwqC{Vu=A``?&^nkKGoft#qZwP7RPF zdNI`?FNBWd5RT=EUCAo@Im;t2v_d-VCGQ)?^DdN1X!G4fT6IodwwC#3jAz~3Mo!S zyzo|h;gQ|6%HBWw)q8oCh2Yua-e_TNLc(TyUGE7J?Ad+(gU8=o5HRxWSq zDogyaX~^Z6WcFqpEz+40rnr%G-x9^S`23Q+nH|Hch|>u@S!n8I7enGj6`oMy{V}{1 zH#UB?yUz~8Z|o|=!W|8c_p_rdHFlhi?w9c2OUy8a!Cxn&HwpQF!C!blWc@PU zn0CUUQ0V)uQfLp}F|FG4b`*cMY3Q1cTBKVR(I z9NPOt!p|3bVuaC8y;M{GJt?}S@u?K8+4*+WlUiv<R!YAS7_(q<~vP^p$mbyTXS(iSRhrP4MkZKu)>Dm_P~1}ZgDX(yF-QE4}o_E2dr zmG)7oiApk+_EYHql@3zrc`6;E(hF2NOr>TjwNU8@m5!qHq*bb{U#V~YSYM4@aN4M@ zU8-zyI;ifLTi3T5JLhx~a-1P8A1|)PE;=U&Iq4$Tsr@NJPBY|%k6Ei12|42;hgM@} zoU??SE2TM4$c0jxmw-4INybZ5x*VcnSBT2ptlY!Oy{z2F%Ka$sbp}{@kd=q1{CW6= zP}P&MkQAz1seJy^s=9m8drRxPUU?D@Ro@DI#-0mnRR^4CMf~~C!{N}OC)H9Yx)MF` zDfF`C^rt(UR^$t7J6}SB_@&PX>s+fm&MK+kR7NVRJ`YDj)o@4NN4)mk<@<-%;s-vB z*RIsHKA8QqVXq@qG2oZx2^$giT z2zk@ChVRwHLX8At9EZU9-NOCTybrg8nMNb1K;t;0I_UPVufaD2i4?zcv-%9(%wfH4xe|@|Q%H9%!`d?r}-Q`qR;rOBVVk>n`AMV0<9lTB* zKlB+JgZ`j*z2O>lpoE+#;gGzl4x^iYkXwzPbT%=pmaxM83lAgA#L=b>gr>%0Pr|XP zPN$BM?BmT|X9SU^Uid(y5f%?eA*9p9Xj(Z5|C z_Hh)mmN##H2>2rAFJpiS%;D3YK;6U65QkrOd3@z#pckAg936Jiw?0m;#?Lz=936Gh zW!~Rajv^3n#_bQmqSv{`;qh`73P&ddaoa<1?r|nLd|kjygEu(%is0Z*_8V-nPqE2< zGvrKjDqOcRCA>)n(m6IO*f9;xad2LM&1>-%$Kc@W9>|q-hr{>}UX1Bi*5ZeqG{-Wf zSe9c8F6L_FOB^)?Q`Wu3!JGhD_jwNDT`I1-V{7qFXNiM%1qh!z>MV1xAi(yuc!%?4 z4!$8k*3p|Bd`p1LrM|+!%N1@%$JgQ~oGvy`pL7fG{Q_jY4{&f$ zfUNf+4h{?O+&53Ub{k@LdzsnoO2`@Egx3Y((Unu`YWy|l2FG6!c(*&hr`i0z#pd^I zn4Oc&Gcp7UMzy`^8mP86j)Q6k1sKEaBuv9DhLeh>GqhlwrS;;Rb0f@V#%nIorIq7X z)*GfNM4=yzSI+XvmE9*lnP6Q-n~qaNIzbWXq%+5<76n!7%E|HdhJNBP7;=_)?Hi)D z^ONV-8>Xo8m5}o$uk4O65m$C&`m8s+N|mpLoSq1uw5)RZ{*m>Dm#Jnrth5LezlyNn(E5ndCLEl+?K0 zPV<`AL=Cu|p*H6njn~Y2HB2it%(-fqbJdb_&2h4RT3_EStn6l!cOb?r_ObxEMk7rZ zXmvuW6NQPcaGEKPX64k?)%cimljE-lymjUD$ZCAlndbN{KYp9zuL=CrCrKu0Wz!W* zgUZHX7%*Nn0w?B#i-HjDIk8=IemBULTV5~u90bjNh&n^-(Xot{cI zs(yl3>W)5`r0_Ao!9hXGma`!azAQi(?!0q_gTn$mzH;vRYW#*X!tqgopIzy?y&8Yj zxytb|j^AfX>@|+z|AUoiTjAh@0NJ`R$-(PxYvwvPI5x$w{JjjV5;r;a3d0t^zPNIz zYc<~OOmp~_3oot3o1EJmd)39>TJ0EHjbC$A4!=gQrxuNaGcNcM(^Z0lvo3=#uf-2K Qa}4|Ka2`&_{=44q0imJ;>Hq)$ literal 0 HcmV?d00001 diff --git a/src/intel/dev/__pycache__/intel_device_info.cpython-314.pyc b/src/intel/dev/__pycache__/intel_device_info.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a174940ad9c2378d2010f03bacd69ba69dccd3e6 GIT binary patch literal 20452 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 khhHby7mLclg(5JV!Z literal 0 HcmV?d00001 diff --git a/src/intel/genxml/__pycache__/intel_genxml.cpython-313.pyc b/src/intel/genxml/__pycache__/intel_genxml.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7bc86ecbcf3c6058a416fcd23647fd372c493e89 GIT binary patch literal 25369 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 literal 0 HcmV?d00001 diff --git a/src/intel/genxml/__pycache__/util.cpython-313.pyc b/src/intel/genxml/__pycache__/util.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6fe91fd86ef8fd5a1d83fbcb7ef8efcdd1fccbb3 GIT binary patch literal 706 zcmZuuOKTHR6h3!mLfQ-=p*|2Bq^6Q~jLEE`SZa<`H<+++<1^C)Z@kJmS3*(5_}_ zRtBNyPPhFtQpv(HxDa&XPMkmBxid*c@W6ccyzV{c`z9$C3xL-9aP#O>4&b{8mL@Np zWEY(iFu))Oz`%r#v~2l%R>6>3B#U22hI}2EY$%AzkZ8G|qR>8G?``O2&ph1L%*Iah z&V#+p+HG^IS~tzZy1lrZKA|9r@ktZm1bS&wKxetsMFw!KF0>Xa-2zQ&#|UxJa>paf zpLl&g@Pk<9lV_(SR(#8&T#VX?AL^sPqdIjh#`VW6IHGpQb;l2>+Zb7F&=@jnJaTNV zb7p6GeMtS6o~utn$8C;Z#cCMzmvfj<@&Ag4m)BTL!d1-C- zWP1Es!Af+%RP5JsvBYScw*znNxRi-Xp7ov8R*lE_xFqL6a>$R9u9idFys literal 0 HcmV?d00001 diff --git a/src/intel/genxml/__pycache__/util.cpython-314.pyc b/src/intel/genxml/__pycache__/util.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8bb3edac5970b3a10dc9942d6a0a11294b5758f4 GIT binary patch literal 739 zcmZuvOKTHR6h3z{A#E-(p+2!eYy*igkJ$vpqUk0JMJQpAZZc^YlQEexFYcX@+SM#| zQ4DT$r`!G+sb*mrTnKgJPK-amb0?FE;DvnmyzV*Y`zEyuxh&x6z2DgXm0?neI)@Ay+sXF5=4Aa1Lxs34GIPdM_gCyMyIeCX~H_KYke@gzxm)7h3#8 zi|^DAmu9qlBA4fwfPZKUaxv{m{6;&M1PLa#hh+DleqFp>oc~GEN^+It9^*De{DQks zPa@(Hy-+ZT3GpH_Kuc^LWlSE^U>WolYOz(3SmpXNV<0qSdGt3$x`q(KS9)dY&uB61 zoYMT19Nm4r{c0Ntf2PIL{Mz)%(cw!OGvQ-KvA&v)BxXdJp=*1lWib5jK|DHcdkk^W zV&uww+Z_d#(PkI1NQl5o2tQMVkog@T*>8olx7jz@ll6PE!d963B}t_6dqpONxXB+{ Cu8z(C literal 0 HcmV?d00001 diff --git a/src/intel/vulkan_hasvk/anv_batch_chain.c b/src/intel/vulkan_hasvk/anv_batch_chain.c index 2ecb8a4..5fbc50e 100644 --- a/src/intel/vulkan_hasvk/anv_batch_chain.c +++ b/src/intel/vulkan_hasvk/anv_batch_chain.c @@ -274,9 +274,62 @@ anv_reloc_list_append(struct anv_reloc_list *list, return VK_SUCCESS; } -/*-----------------------------------------------------------------------* - * Functions related to anv_batch - *-----------------------------------------------------------------------*/ +/* Like anv_reloc_list_append(), but only copies/rebases the relocations + * whose offset falls at or after @skip_bytes -- i.e. the ones that belong + * to the suffix of @other starting at that byte, which is what + * anv_batch_emit_batch_suffix() actually copies into @batch. Relocations + * before @skip_bytes belong to a region we are deliberately NOT emitting + * and must not be added (their target offset would land outside what we + * copied, corrupting the batch). + */ +static VkResult +anv_reloc_list_append_range(struct anv_reloc_list *list, + const VkAllocationCallbacks *alloc, + struct anv_reloc_list *other, + uint32_t skip_bytes, uint32_t offset) +{ + uint32_t n = 0; + for (uint32_t i = 0; i < other->num_relocs; i++) { + if (other->relocs[i].offset >= skip_bytes) + n++; + } + + if (n == 0) { + /* Still need to propagate BO dependencies: shaders/state referenced + * only from the skipped prefix may not be otherwise declared as + * used by this command buffer submission if this is the very first + * time this pipeline's group is touched in it. + */ + anv_reloc_list_grow_deps(list, alloc, other->dep_words); + for (uint32_t w = 0; w < other->dep_words; w++) + list->deps[w] |= other->deps[w]; + return VK_SUCCESS; + } + + VkResult result = anv_reloc_list_grow(list, alloc, n); + if (result != VK_SUCCESS) + return result; + + uint32_t j = list->num_relocs; + for (uint32_t i = 0; i < other->num_relocs; i++) { + if (other->relocs[i].offset < skip_bytes) + continue; + list->relocs[j] = other->relocs[i]; + list->relocs[j].offset += offset - skip_bytes; + list->reloc_bos[j] = other->reloc_bos[i]; + j++; + } + assert(j == list->num_relocs + n); + list->num_relocs = j; + + anv_reloc_list_grow_deps(list, alloc, other->dep_words); + for (uint32_t w = 0; w < other->dep_words; w++) + list->deps[w] |= other->deps[w]; + + return VK_SUCCESS; +} + + void * anv_batch_emit_dwords(struct anv_batch *batch, int num_dwords) @@ -340,7 +393,45 @@ anv_batch_emit_batch(struct anv_batch *batch, struct anv_batch *other) batch->next += size; } -/*-----------------------------------------------------------------------* +void +anv_batch_emit_batch_suffix(struct anv_batch *batch, struct anv_batch *other, + uint32_t skip_bytes) +{ + uint32_t full_size = other->next - other->start; + assert(skip_bytes <= full_size); + assert(skip_bytes % 4 == 0); + uint32_t size = full_size - skip_bytes; + + if (size == 0) + return; + assert(size % 4 == 0); + + if (batch->next + size > batch->end) { + VkResult result = batch->extend_cb(batch, batch->user_data); + if (result != VK_SUCCESS) { + anv_batch_set_error(batch, result); + return; + } + } + + assert(batch->next + size <= batch->end); + + VG(VALGRIND_CHECK_MEM_IS_DEFINED(other->start + skip_bytes, size)); + memcpy(batch->next, other->start + skip_bytes, size); + + uint32_t offset = batch->next - batch->start; + VkResult result = anv_reloc_list_append_range(batch->relocs, batch->alloc, + other->relocs, + skip_bytes, offset); + if (result != VK_SUCCESS) { + anv_batch_set_error(batch, result); + return; + } + + batch->next += size; +} + +/*----------------------------------------------------------------------- * Functions related to anv_batch_bo *-----------------------------------------------------------------------*/ diff --git a/src/intel/vulkan_hasvk/anv_image.c b/src/intel/vulkan_hasvk/anv_image.c index 90b2309..e0c7b9f 100644 --- a/src/intel/vulkan_hasvk/anv_image.c +++ b/src/intel/vulkan_hasvk/anv_image.c @@ -569,17 +569,12 @@ add_aux_surface_if_supported(struct anv_device *device, return VK_SUCCESS; } - if (device->info->ver == 7) { - anv_perf_warn(VK_LOG_OBJS(&image->vk.base), "Implement gfx7 HiZ"); - return VK_SUCCESS; - } - if (image->vk.mip_levels > 1) { anv_perf_warn(VK_LOG_OBJS(&image->vk.base), "Enable multi-LOD HiZ"); return VK_SUCCESS; } - if (device->info->ver == 8 && image->vk.samples > 1) { + if (device->info->ver <= 8 && image->vk.samples > 1) { anv_perf_warn(VK_LOG_OBJS(&image->vk.base), "Enable gfx8 multisampled HiZ"); return VK_SUCCESS; diff --git a/src/intel/vulkan_hasvk/anv_private.h b/src/intel/vulkan_hasvk/anv_private.h index dad8b1a..d82fa9d 100644 --- a/src/intel/vulkan_hasvk/anv_private.h +++ b/src/intel/vulkan_hasvk/anv_private.h @@ -1339,6 +1339,17 @@ struct anv_batch { void *anv_batch_emit_dwords(struct anv_batch *batch, int num_dwords); void anv_batch_emit_batch(struct anv_batch *batch, struct anv_batch *other); + +/* Like anv_batch_emit_batch(), but only copies the suffix of @other + * starting at byte offset @skip_bytes (and only appends/rebases the + * relocations that fall within that suffix). Gen7-only: used to skip + * re-emitting a pipeline's VS-stage instruction group when it is + * byte-identical to what's already programmed for the previous bind + * (see cmd_buffer_flush_gfx_state). + */ +void anv_batch_emit_batch_suffix(struct anv_batch *batch, + struct anv_batch *other, + uint32_t skip_bytes); struct anv_address anv_batch_address(struct anv_batch *batch, void *batch_location); static inline void @@ -2399,6 +2410,30 @@ struct anv_cmd_graphics_state { struct anv_graphics_pipeline *pipeline; + /** Last emitted URB configuration (Gen7 stall optimization) */ + struct intel_urb_config last_urb_cfg; + bool urb_cfg_valid; + + /** + * Gen7 VS-stage instruction group cache. Tracks the VS/TCS/TES/GS + * shader binaries AND the effective URB config (see last_urb_cfg + * above) of the pipeline for which the group (URB + VS + HS + DS + + * GS, plus the PRM-mandated depth-stall PIPE_CONTROL before them) was + * last fully emitted into this command buffer, so a subsequent bind + * can skip re-emitting the whole group when both match the previous + * bind. Shader pointers alone are not sufficient -- URB layout also + * depends on l3_config. Always present (not #if-guarded) so this + * struct's layout doesn't depend on GFX_VER; only read/written by + * Gen7 code paths, inert everywhere else. + */ + struct anv_shader_bin *vs_stage_key[4]; + bool vs_stage_key_valid; + /** True once a stall satisfying the PRM's VS-associated-3DSTATE rule + * has been emitted for the *current* draw's pipeline flush. Used to + * decide whether a later VS-descriptor/push-constant update still + * needs its own stall (see cmd_buffer_flush_gfx_state). */ + bool vs_stage_stall_emitted; + VkRenderingFlags rendering_flags; VkRect2D render_area; uint32_t layer_count; @@ -2790,6 +2825,22 @@ struct anv_pipeline { struct anv_graphics_pipeline { struct anv_pipeline base; + /* URB configuration computed at pipeline creation time. + * Used to skip redundant URB re-emission and PIPE_CONTROL stalls on Gen7. + */ + struct intel_urb_config urb_cfg; + + /* Byte length, from the start of base.batch, of the VS-stage + * instruction group (3DSTATE_URB_* + 3DSTATE_VS + 3DSTATE_HS + + * 3DSTATE_DS + 3DSTATE_GS, plus the PRM-mandated depth-stall + * PIPE_CONTROL emitted just before them). Computed unconditionally in + * genX(graphics_pipeline_emit) so this struct's layout doesn't depend + * on GFX_VER; only meaningful/consumed on Gen7 (0 elsewhere, since the + * reordering that makes the group a contiguous prefix of base.batch + * only happens for GFX_VER <= 7). + */ + uint32_t vs_stage_batch_size; + /* Shaders */ struct anv_shader_bin * shaders[ANV_GRAPHICS_SHADER_STAGE_COUNT]; diff --git a/src/intel/vulkan_hasvk/genX_cmd_buffer.c b/src/intel/vulkan_hasvk/genX_cmd_buffer.c index 4abc736..3683705 100644 --- a/src/intel/vulkan_hasvk/genX_cmd_buffer.c +++ b/src/intel/vulkan_hasvk/genX_cmd_buffer.c @@ -3352,8 +3352,84 @@ genX(cmd_buffer_flush_gfx_state)(struct anv_cmd_buffer *cmd_buffer) } } +#if GFX_VER <= 7 + /* Reset for this flush cycle; set true below the moment a stall + * covering the PRM's VS-associated-3DSTATE rule has actually been + * emitted, whichever path ends up doing it. */ + cmd_buffer->state.gfx.vs_stage_stall_emitted = false; +#endif + if (cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_PIPELINE) { +#if GFX_VER <= 7 + /* Skip re-emitting the VS-stage instruction group (URB + VS + HS + + * DS + GS, plus its PRM-mandated depth-stall PIPE_CONTROL, all kept + * contiguous at the front of the pipeline's static batch -- see + * genX(graphics_pipeline_emit)) when it is byte-identical to what's + * already programmed. This requires BOTH the same VS/TCS/TES/GS + * shader binaries AND the same effective URB config as the last + * pipeline for which we fully emitted the group -- shader pointers + * alone are not enough, since URB start/entry-count also depends on + * l3_config (see the urb_unchanged check below). Two different + * VkPipeline objects that share the same shaders and l3_config + * (e.g. VulkanMod's opaque vs. cutout terrain pipelines, which only + * differ in rasterizer cull mode) hit this path every switch. + */ + struct anv_cmd_graphics_state *gfx_state = &cmd_buffer->state.gfx; + struct anv_shader_bin *new_key[4] = { + pipeline->shaders[MESA_SHADER_VERTEX], + pipeline->shaders[MESA_SHADER_TESS_CTRL], + pipeline->shaders[MESA_SHADER_TESS_EVAL], + pipeline->shaders[MESA_SHADER_GEOMETRY], + }; + + /* Same shaders alone is NOT sufficient: the actual URB byte layout + * (VSURBStartingAddress / VSNumberofURBEntries) also depends on + * l3_config (e.g. render target/attachment count shifts L3 + * partitioning -- see intel_get_urb_config()), so two pipelines + * with byte-identical VS/HS/DS/GS shaders can still need a + * different URB layout. Must check both. + */ + bool urb_unchanged = gfx_state->urb_cfg_valid; + if (urb_unchanged) { + for (int s = MESA_SHADER_VERTEX; s <= MESA_SHADER_GEOMETRY; s++) { + if (intel_urb_setup_changed(&gfx_state->last_urb_cfg, + &pipeline->urb_cfg, s)) { + urb_unchanged = false; + break; + } + } + } + + bool vs_stage_unchanged = + gfx_state->vs_stage_key_valid && + memcmp(gfx_state->vs_stage_key, new_key, sizeof(new_key)) == 0 && + urb_unchanged; + vs_stage_unchanged = false; /* DIAGNOSTIC: force full emit, see script header */ + + if (vs_stage_unchanged) { + anv_batch_emit_batch_suffix(&cmd_buffer->batch, &pipeline->base.batch, + pipeline->vs_stage_batch_size); + /* We skipped the group -- no stall owed for URB/VS/HS/DS/GS + * themselves, but if descriptors/push-constants are ALSO dirty + * this flush cycle, 3DSTATE_CONSTANT_VS / + * 3DSTATE_BINDING_TABLE_POINTER_VS are still about to be emitted + * below and are covered by the SAME PRM rule -- so do NOT mark + * vs_stage_stall_emitted here; let the check below decide. + */ + } else { + anv_batch_emit_batch(&cmd_buffer->batch, &pipeline->base.batch); + memcpy(gfx_state->vs_stage_key, new_key, sizeof(new_key)); + gfx_state->vs_stage_key_valid = true; + gfx_state->last_urb_cfg = pipeline->urb_cfg; + gfx_state->urb_cfg_valid = true; + /* Full emit -- the PIPE_CONTROL baked into the pipeline's static + * batch (by emit_urb_setup) was actually sent, covering the + * whole PRM-mandated group for this flush cycle. */ + gfx_state->vs_stage_stall_emitted = true; + } +#else anv_batch_emit_batch(&cmd_buffer->batch, &pipeline->base.batch); +#endif /* If the pipeline changed, we may need to re-allocate push constant * space in the URB. @@ -3362,8 +3438,9 @@ genX(cmd_buffer_flush_gfx_state)(struct anv_cmd_buffer *cmd_buffer) } #if GFX_VER <= 7 - if (cmd_buffer->state.descriptors_dirty & VK_SHADER_STAGE_VERTEX_BIT || - cmd_buffer->state.push_constants_dirty & VK_SHADER_STAGE_VERTEX_BIT) { + if (!cmd_buffer->state.gfx.vs_stage_stall_emitted && + (cmd_buffer->state.descriptors_dirty & VK_SHADER_STAGE_VERTEX_BIT || + cmd_buffer->state.push_constants_dirty & VK_SHADER_STAGE_VERTEX_BIT)) { /* From the IVB PRM Vol. 2, Part 1, Section 3.2.1: * * "A PIPE_CONTROL with Post-Sync Operation set to 1h and a depth @@ -3380,6 +3457,7 @@ genX(cmd_buffer_flush_gfx_state)(struct anv_cmd_buffer *cmd_buffer) pc.Address = cmd_buffer->device->workaround_address; anv_debug_dump_pc(pc); } + cmd_buffer->state.gfx.vs_stage_stall_emitted = true; } #endif diff --git a/src/intel/vulkan_hasvk/genX_pipeline.c b/src/intel/vulkan_hasvk/genX_pipeline.c index f727f1c..d4a950c 100644 --- a/src/intel/vulkan_hasvk/genX_pipeline.c +++ b/src/intel/vulkan_hasvk/genX_pipeline.c @@ -325,6 +325,28 @@ emit_urb_setup(struct anv_graphics_pipeline *pipeline) entry_size[i] = prog_data ? prog_data->urb_entry_size : 1; } +#if GFX_VER <= 7 + /* Compute and cache the *actual* URB config -- not just the shaders' + * requested entry sizes, but the real per-stage start offsets and + * entry counts, which also depend on l3_config (e.g. attachment/RT + * count can shift L3 partitioning). This is the correct, complete key + * for cmd_buffer_flush_gfx_state() to decide whether the VS-stage + * instruction group can be skipped on a later bind: two pipelines + * with byte-identical VS/HS/DS/GS shaders can still require a + * different URB layout if their l3_config differs -- comparing shader + * pointers alone is not sufficient. + */ + pipeline->urb_cfg = (struct intel_urb_config) { + .size = { entry_size[0], entry_size[1], entry_size[2], entry_size[3] }, + }; + bool urb_constrained; + intel_get_urb_config(pipeline->base.device->info, pipeline->base.l3_config, + pipeline->active_stages & + VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, + pipeline->active_stages & VK_SHADER_STAGE_GEOMETRY_BIT, + &pipeline->urb_cfg, &urb_constrained); +#endif + genX(emit_urb_setup)(pipeline->base.device, &pipeline->base.batch, pipeline->base.l3_config, pipeline->active_stages, entry_size); @@ -1827,6 +1849,16 @@ genX(graphics_pipeline_emit)(struct anv_graphics_pipeline *pipeline, { emit_urb_setup(pipeline); + /* DIAGNOSTIC v2: VS/HS/DS/GS reordering reverted -- back to vanilla + * emission position (after vertex_input, below). vs_stage_batch_size + * is set to 0 here since it's meaningless with the group no longer + * contiguous with URB; this is fine because diagnostic v1 already + * force-disabled the skip path that would have used it. + */ +#if GFX_VER <= 7 + pipeline->vs_stage_batch_size = 0; +#endif + assert(state->rs != NULL); emit_rs_state(pipeline, state->ia, state->rs, state->ms, state->rp); emit_ms_state(pipeline, state->ms); @@ -1856,6 +1888,8 @@ genX(graphics_pipeline_emit)(struct anv_graphics_pipeline *pipeline, emit_vertex_input(pipeline, state->vi); + /* DIAGNOSTIC v2: always emit here (both Gen7 and Gen8+), matching + * vanilla hasvk's original position exactly. */ emit_3dstate_vs(pipeline); emit_3dstate_hs_te_ds(pipeline, state->ts); emit_3dstate_gs(pipeline, state->rs); diff --git a/src/intel/vulkan_hasvk/gfx7_cmd_buffer.c b/src/intel/vulkan_hasvk/gfx7_cmd_buffer.c index ef653ab..0a13541 100644 --- a/src/intel/vulkan_hasvk/gfx7_cmd_buffer.c +++ b/src/intel/vulkan_hasvk/gfx7_cmd_buffer.c @@ -232,7 +232,8 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer) */ if ((cmd_buffer->state.gfx.dirty & ANV_CMD_DIRTY_PIPELINE) || BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_IA_PRIMITIVE_TOPOLOGY) || - BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES)) { + BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES) || + BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RS_LINE_STIPPLE)) { VkPolygonMode dynamic_raster_mode = genX(raster_polygon_mode)(cmd_buffer->state.gfx.pipeline, dyn->ia.primitive_topology); @@ -243,10 +244,13 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer) .ThreadDispatchEnable = anv_pipeline_has_stage(pipeline, MESA_SHADER_FRAGMENT) && (pipeline->force_fragment_thread_dispatch || - !anv_cmd_buffer_all_color_write_masked(cmd_buffer)), + !anv_cmd_buffer_all_color_write_masked(cmd_buffer)), .MultisampleRasterizationMode = genX(ms_rasterization_mode)(pipeline, dynamic_raster_mode), + #if GFX_VERx10 == 70 + .LineStippleEnable = dyn->rs.line.stipple.enable, + #endif }; GENX(3DSTATE_WM_pack)(NULL, dwords, &wm);