From 9fbac1ee739eea9c12f12db743cce992175fddcf Mon Sep 17 00:00:00 2001 From: elwrcl Date: Mon, 21 Sep 2026 22:55:11 +0300 Subject: [PATCH] elk: vec4 arka ucunda fp64 float-controls emisyonunu tamamla vec4_visitor::emit_shader_float_controls_execution_mode() yalnizca ELK_SHADER_OPCODE_RND_MODE emit ediyordu; denorm modunu hic yazmiyordu. SIMD arka ucu ikisini birden ELK_SHADER_OPCODE_FLOAT_CONTROL_MODE ile yaziyor. Gen7'de VS/GS/TCS/TES vec4 kullandigi icin bu asamalarda fp64 denorm semantigi sessizce yanlisti. Donanim yapabiliyor -- IVB PRM vol4 part3, CR0 bit 6 "Double Precision Denorm Mode" ve bit 5:4 "Rounding Mode", elk'in ELK_CR0_* sabitleriyle birebir ortusuyor. Eksik olan yalnizca emisyondu; elk_vec4_generator.cpp da o opcode'u hic ele almiyordu. elk_rnd_mode_from_nir() elk_fs_nir.cpp'den elk_nir.c'ye tasindi, iki arka uc paylasiyor. VK-GL-CTS, 8086:0166 (IVB GT2), 9402 fp64 vakasi: oncesi: 3943 Pass / 52 Fail sonrasi: 3975 Pass / 20 Fail Gerileme yok: draw/vertex_input/tess/geom diliminde dusen 166 vaka degisiklik geri alinarak tekrar kosuldu, hepsi ayni sekilde dusuyor. Co-Authored-By: Claude Opus 5 --- src/intel/compiler/elk/elk_fs_nir.cpp | 46 ------------------ src/intel/compiler/elk/elk_nir.c | 47 +++++++++++++++++++ src/intel/compiler/elk/elk_nir.h | 6 +++ src/intel/compiler/elk/elk_vec4_generator.cpp | 6 +++ src/intel/compiler/elk/elk_vec4_visitor.cpp | 34 ++++++++------ 5 files changed, 78 insertions(+), 61 deletions(-) diff --git a/src/intel/compiler/elk/elk_fs_nir.cpp b/src/intel/compiler/elk/elk_fs_nir.cpp index 74b9ea1..b4b8da9 100644 --- a/src/intel/compiler/elk/elk_fs_nir.cpp +++ b/src/intel/compiler/elk/elk_fs_nir.cpp @@ -6947,52 +6947,6 @@ fs_nir_emit_instr(nir_to_elk_state &ntb, nir_instr *instr) } } -static unsigned -elk_rnd_mode_from_nir(unsigned mode, unsigned *mask) -{ - unsigned elk_mode = 0; - *mask = 0; - - if ((FLOAT_CONTROLS_ROUNDING_MODE_RTZ_FP16 | - FLOAT_CONTROLS_ROUNDING_MODE_RTZ_FP32 | - FLOAT_CONTROLS_ROUNDING_MODE_RTZ_FP64) & - mode) { - elk_mode |= ELK_RND_MODE_RTZ << ELK_CR0_RND_MODE_SHIFT; - *mask |= ELK_CR0_RND_MODE_MASK; - } - if ((FLOAT_CONTROLS_ROUNDING_MODE_RTE_FP16 | - FLOAT_CONTROLS_ROUNDING_MODE_RTE_FP32 | - FLOAT_CONTROLS_ROUNDING_MODE_RTE_FP64) & - mode) { - elk_mode |= ELK_RND_MODE_RTNE << ELK_CR0_RND_MODE_SHIFT; - *mask |= ELK_CR0_RND_MODE_MASK; - } - if (mode & FLOAT_CONTROLS_DENORM_PRESERVE_FP16) { - elk_mode |= ELK_CR0_FP16_DENORM_PRESERVE; - *mask |= ELK_CR0_FP16_DENORM_PRESERVE; - } - if (mode & FLOAT_CONTROLS_DENORM_PRESERVE_FP32) { - elk_mode |= ELK_CR0_FP32_DENORM_PRESERVE; - *mask |= ELK_CR0_FP32_DENORM_PRESERVE; - } - if (mode & FLOAT_CONTROLS_DENORM_PRESERVE_FP64) { - elk_mode |= ELK_CR0_FP64_DENORM_PRESERVE; - *mask |= ELK_CR0_FP64_DENORM_PRESERVE; - } - if (mode & FLOAT_CONTROLS_DENORM_FLUSH_TO_ZERO_FP16) - *mask |= ELK_CR0_FP16_DENORM_PRESERVE; - if (mode & FLOAT_CONTROLS_DENORM_FLUSH_TO_ZERO_FP32) - *mask |= ELK_CR0_FP32_DENORM_PRESERVE; - if (mode & FLOAT_CONTROLS_DENORM_FLUSH_TO_ZERO_FP64) - *mask |= ELK_CR0_FP64_DENORM_PRESERVE; - if (mode == FLOAT_CONTROLS_DEFAULT_FLOAT_CONTROL_MODE) - *mask |= ELK_CR0_FP_MODE_MASK; - - if (*mask != 0) - assert((*mask & elk_mode) == elk_mode); - - return elk_mode; -} static void emit_shader_float_controls_execution_mode(nir_to_elk_state &ntb) diff --git a/src/intel/compiler/elk/elk_nir.c b/src/intel/compiler/elk/elk_nir.c index cef363b..2724976 100644 --- a/src/intel/compiler/elk/elk_nir.c +++ b/src/intel/compiler/elk/elk_nir.c @@ -2016,3 +2016,50 @@ elk_nir_get_var_type(const struct nir_shader *nir, nir_variable *var) return type; } +unsigned +elk_rnd_mode_from_nir(unsigned mode, unsigned *mask) +{ + unsigned elk_mode = 0; + *mask = 0; + + if ((FLOAT_CONTROLS_ROUNDING_MODE_RTZ_FP16 | + FLOAT_CONTROLS_ROUNDING_MODE_RTZ_FP32 | + FLOAT_CONTROLS_ROUNDING_MODE_RTZ_FP64) & + mode) { + elk_mode |= ELK_RND_MODE_RTZ << ELK_CR0_RND_MODE_SHIFT; + *mask |= ELK_CR0_RND_MODE_MASK; + } + if ((FLOAT_CONTROLS_ROUNDING_MODE_RTE_FP16 | + FLOAT_CONTROLS_ROUNDING_MODE_RTE_FP32 | + FLOAT_CONTROLS_ROUNDING_MODE_RTE_FP64) & + mode) { + elk_mode |= ELK_RND_MODE_RTNE << ELK_CR0_RND_MODE_SHIFT; + *mask |= ELK_CR0_RND_MODE_MASK; + } + if (mode & FLOAT_CONTROLS_DENORM_PRESERVE_FP16) { + elk_mode |= ELK_CR0_FP16_DENORM_PRESERVE; + *mask |= ELK_CR0_FP16_DENORM_PRESERVE; + } + if (mode & FLOAT_CONTROLS_DENORM_PRESERVE_FP32) { + elk_mode |= ELK_CR0_FP32_DENORM_PRESERVE; + *mask |= ELK_CR0_FP32_DENORM_PRESERVE; + } + if (mode & FLOAT_CONTROLS_DENORM_PRESERVE_FP64) { + elk_mode |= ELK_CR0_FP64_DENORM_PRESERVE; + *mask |= ELK_CR0_FP64_DENORM_PRESERVE; + } + if (mode & FLOAT_CONTROLS_DENORM_FLUSH_TO_ZERO_FP16) + *mask |= ELK_CR0_FP16_DENORM_PRESERVE; + if (mode & FLOAT_CONTROLS_DENORM_FLUSH_TO_ZERO_FP32) + *mask |= ELK_CR0_FP32_DENORM_PRESERVE; + if (mode & FLOAT_CONTROLS_DENORM_FLUSH_TO_ZERO_FP64) + *mask |= ELK_CR0_FP64_DENORM_PRESERVE; + if (mode == FLOAT_CONTROLS_DEFAULT_FLOAT_CONTROL_MODE) + *mask |= ELK_CR0_FP_MODE_MASK; + + if (*mask != 0) + assert((*mask & elk_mode) == elk_mode); + + return elk_mode; +} + diff --git a/src/intel/compiler/elk/elk_nir.h b/src/intel/compiler/elk/elk_nir.h index 0febcb5..7c86488 100644 --- a/src/intel/compiler/elk/elk_nir.h +++ b/src/intel/compiler/elk/elk_nir.h @@ -261,6 +261,12 @@ const struct glsl_type *elk_nir_get_var_type(const struct nir_shader *nir, void elk_nir_adjust_payload(nir_shader *shader); + +/* Bir NIR float_controls_execution_mode degerini CR0 bit deseni + + * maskeye cevirir. Hem SIMD (fs) hem vec4 arka ucu kullanir. + */ +unsigned elk_rnd_mode_from_nir(unsigned mode, unsigned *mask); + #ifdef __cplusplus } #endif diff --git a/src/intel/compiler/elk/elk_vec4_generator.cpp b/src/intel/compiler/elk/elk_vec4_generator.cpp index 9b63b7a..8401a92 100644 --- a/src/intel/compiler/elk/elk_vec4_generator.cpp +++ b/src/intel/compiler/elk/elk_vec4_generator.cpp @@ -2180,6 +2180,12 @@ generate_code(struct elk_codegen *p, } break; + case ELK_SHADER_OPCODE_FLOAT_CONTROL_MODE: + assert(src[0].file == ELK_IMMEDIATE_VALUE); + assert(src[1].file == ELK_IMMEDIATE_VALUE); + elk_float_controls_mode(p, src[0].d, src[1].d); + break; + default: UNREACHABLE("Unsupported opcode"); } diff --git a/src/intel/compiler/elk/elk_vec4_visitor.cpp b/src/intel/compiler/elk/elk_vec4_visitor.cpp index 27c0652..dcb8cb8 100644 --- a/src/intel/compiler/elk/elk_vec4_visitor.cpp +++ b/src/intel/compiler/elk/elk_vec4_visitor.cpp @@ -6,6 +6,7 @@ #include "elk_vec4.h" #include "elk_cfg.h" #include "elk_eu.h" +#include "elk_nir.h" #include "util/u_math.h" namespace elk { @@ -1334,25 +1335,28 @@ vec4_visitor::resolve_ud_negate(src_reg *reg) *reg = temp; } -static elk_rnd_mode -elk_rnd_mode_from_execution_mode(unsigned execution_mode) -{ - if (nir_has_any_rounding_mode_rtne(execution_mode)) - return ELK_RND_MODE_RTNE; - if (nir_has_any_rounding_mode_rtz(execution_mode)) - return ELK_RND_MODE_RTZ; - return ELK_RND_MODE_UNSPECIFIED; -} - void vec4_visitor::emit_shader_float_controls_execution_mode() { unsigned execution_mode = this->nir->info.float_controls_execution_mode; - if (nir_has_any_rounding_mode_enabled(execution_mode)) { - elk_rnd_mode rnd = elk_rnd_mode_from_execution_mode(execution_mode); - const vec4_builder bld = vec4_builder(this).at_end(); - bld.exec_all().emit(ELK_SHADER_OPCODE_RND_MODE, dst_null_ud(), elk_imm_d(rnd)); - } + if (execution_mode == FLOAT_CONTROLS_DEFAULT_FLOAT_CONTROL_MODE) + return; + + /* Eskiden burada sadece ELK_SHADER_OPCODE_RND_MODE emit ediliyordu, yani + * yuvarlama modu ayarlaniyor ama denorm modu hic dokunulmadan birakiliyordu. + * SIMD arka ucu (elk_fs_nir.cpp) ikisini birden tek bir + * ELK_SHADER_OPCODE_FLOAT_CONTROL_MODE ile yaziyor; vec4 arka ucunun geride + * kalmasi, gen7'de VS/GS/TCS/TES asamalarinda fp64 denorm semantiginin + * sessizce yanlis olmasina yol aciyordu (CR0 bit 6, IVB PRM vol4 part3: + * "Double Precision Denorm Mode ... initialized by Thread Dispatch"). + */ + unsigned mask, mode = elk_rnd_mode_from_nir(execution_mode, &mask); + if (mask == 0) + return; + + const vec4_builder bld = vec4_builder(this).at_end(); + bld.exec_all().emit(ELK_SHADER_OPCODE_FLOAT_CONTROL_MODE, dst_null_ud(), + elk_imm_d(mode), elk_imm_d(mask)); } vec4_visitor::vec4_visitor(const struct elk_compiler *compiler,