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 <[email protected]>
This commit is contained in:
elwrclandClaude Opus 5 committed 2026-09-21 22:55:40 +03:00
1 parent 785e5e4fa4
commit 9fbac1ee73
5 files changed
+78 -61

No files matched your search

-46
View File
@@ -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 static void
emit_shader_float_controls_execution_mode(nir_to_elk_state &ntb) emit_shader_float_controls_execution_mode(nir_to_elk_state &ntb)
+47
View File
@@ -2016,3 +2016,50 @@ elk_nir_get_var_type(const struct nir_shader *nir, nir_variable *var)
return type; 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;
}
+6
View File
@@ -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); 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 #ifdef __cplusplus
} }
#endif #endif
@@ -2180,6 +2180,12 @@ generate_code(struct elk_codegen *p,
} }
break; 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: default:
UNREACHABLE("Unsupported opcode"); UNREACHABLE("Unsupported opcode");
} }
+19 -15
View File
@@ -6,6 +6,7 @@
#include "elk_vec4.h" #include "elk_vec4.h"
#include "elk_cfg.h" #include "elk_cfg.h"
#include "elk_eu.h" #include "elk_eu.h"
#include "elk_nir.h"
#include "util/u_math.h" #include "util/u_math.h"
namespace elk { namespace elk {
@@ -1334,25 +1335,28 @@ vec4_visitor::resolve_ud_negate(src_reg *reg)
*reg = temp; *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 void
vec4_visitor::emit_shader_float_controls_execution_mode() vec4_visitor::emit_shader_float_controls_execution_mode()
{ {
unsigned execution_mode = this->nir->info.float_controls_execution_mode; unsigned execution_mode = this->nir->info.float_controls_execution_mode;
if (nir_has_any_rounding_mode_enabled(execution_mode)) { if (execution_mode == FLOAT_CONTROLS_DEFAULT_FLOAT_CONTROL_MODE)
elk_rnd_mode rnd = elk_rnd_mode_from_execution_mode(execution_mode); return;
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)); /* 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, vec4_visitor::vec4_visitor(const struct elk_compiler *compiler,