tests/hlsl: Test shader model 6.2 denormal mode for 32-bit floats.

This commit is contained in:
Giovanni Mascellani
2025-10-24 23:36:11 +02:00
committed by Henri Verbeet
parent da6ce78c1c
commit 69c109786b
Notes: Henri Verbeet 2025-10-30 20:00:32 +01:00
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1809
5 changed files with 81 additions and 9 deletions

View File

@@ -479,3 +479,33 @@ uniform 1 uint 0xc7803000 % 0.125 -7.5
draw quad draw quad
% The computation is done in f16, but ULPs are relative to the f32 result. % The computation is done in f16, but ULPs are relative to the f32 result.
probe (0, 0) rgba(-0.0156173706, -6.5, 1.90734863e-06, 15.0) 16384 probe (0, 0) rgba(-0.0156173706, -6.5, 1.90734863e-06, 15.0) 16384
[require]
shader model >= 6.2
[pixel shader]
uniform float2 f;
float4 main() : SV_Target
{
return float4(f.x, f.x / 100.0f, f.x * 100.0f, f.x / f.y);
}
% Some C libraries are unable to parse denormal numbers, so we bitcast to uint
[test]
denorm preserve
uniform 0 float4 1.0e-37 100.0 0.0 0.0
draw quad
todo probe (0, 0) u32(0x02081cea, 0x000ae398, 0x0554ad2e, 0x000ae398) % f32(1.0e-37, 1.0e-39, 1.0e-35, 1.0e-39)
uniform 0 uint4 0x000ae398 0x3c23d70a 0 0 % f32(1.0e-39, 0.01, 0, 0)
draw quad
todo probe (0, 0) u32(0x000ae398, 0x00001be0, 0x02081cec, 0x02081cec) % f32(1.0e-39, 1.0e-41, 9.999989e-38, 9.999989e-38)
denorm ftz
uniform 0 float4 1.0e-37 100.0 0.0 0.0
draw quad
probe (0, 0) u32(0x02081cea, 0x00000000, 0x0554ad2e, 0x00000000) % f32(1.0e-37, 0.0, 1.0e-35, 0.0)
uniform 0 uint4 0x000ae398 0x3c23d70a 0 0 % f32(1.0e-39, 0.01, 0, 0)
draw quad
probe (0, 0) u32(0x000ae398, 0x00000000, 0x00000000, 0x00000000) % f32(1.0e-39, 0.0, 0.0, 0.0)

View File

@@ -1752,6 +1752,17 @@ static void parse_test_directive(struct shader_runner *runner, const char *line)
read_f32(&line, &c->luminance_scale); read_f32(&line, &c->luminance_scale);
read_f32(&line, &c->luminance_offset); read_f32(&line, &c->luminance_offset);
} }
else if (match_string(line, "denorm", &line))
{
if (match_string(line, "preserve", &line))
runner->denorm_mode = DENORM_PRESERVE;
else if (match_string(line, "ftz", &line))
runner->denorm_mode = DENORM_FTZ;
else if (match_string(line, "any", &line))
runner->denorm_mode = DENORM_ANY;
else
fatal_error("Invalid denorm mode '%s'.\n", line);
}
else else
{ {
fatal_error("Unknown test directive '%s'.\n", line); fatal_error("Unknown test directive '%s'.\n", line);
@@ -1882,8 +1893,8 @@ static HRESULT d3d10_blob_from_vkd3d_shader_code(const struct vkd3d_shader_code
return S_OK; return S_OK;
} }
static HRESULT dxc_compiler_compile_shader(void *dxc_compiler, const char *profile, static HRESULT dxc_compiler_compile_shader(void *dxc_compiler, const char *profile, unsigned int compile_options,
unsigned int compile_options, bool enable_16bit_types, const char *hlsl, ID3D10Blob **blob_out) bool enable_16bit_types, enum denorm_mode denorm_mode, const char *hlsl, ID3D10Blob **blob_out)
{ {
struct vkd3d_shader_code blob; struct vkd3d_shader_code blob;
WCHAR wprofile[7]; WCHAR wprofile[7];
@@ -1892,7 +1903,8 @@ static HRESULT dxc_compiler_compile_shader(void *dxc_compiler, const char *profi
*blob_out = NULL; *blob_out = NULL;
swprintf(wprofile, ARRAY_SIZE(wprofile), L"%hs", profile); swprintf(wprofile, ARRAY_SIZE(wprofile), L"%hs", profile);
if (FAILED(hr = dxc_compile(dxc_compiler, wprofile, compile_options, enable_16bit_types, hlsl, &blob))) if (FAILED(hr = dxc_compile(dxc_compiler, wprofile, compile_options,
enable_16bit_types, denorm_mode, hlsl, &blob)))
return hr; return hr;
hr = d3d10_blob_from_vkd3d_shader_code(&blob, blob_out); hr = d3d10_blob_from_vkd3d_shader_code(&blob, blob_out);
@@ -1997,7 +2009,7 @@ ID3D10Blob *compile_hlsl(const struct shader_runner *runner, enum shader_type ty
{ {
assert(runner->dxc_compiler); assert(runner->dxc_compiler);
hr = dxc_compiler_compile_shader(runner->dxc_compiler, profile, options, hr = dxc_compiler_compile_shader(runner->dxc_compiler, profile, options,
runner->require_shader_caps[SHADER_CAP_NATIVE_16_BIT], source, &blob); runner->require_shader_caps[SHADER_CAP_NATIVE_16_BIT], runner->denorm_mode, source, &blob);
} }
else else
{ {
@@ -2106,7 +2118,7 @@ static void compile_shader(struct shader_runner *runner, const char *source,
{ {
assert(runner->dxc_compiler); assert(runner->dxc_compiler);
hr = dxc_compiler_compile_shader(runner->dxc_compiler, profile, options, hr = dxc_compiler_compile_shader(runner->dxc_compiler, profile, options,
runner->require_shader_caps[SHADER_CAP_NATIVE_16_BIT], source, &blob); runner->require_shader_caps[SHADER_CAP_NATIVE_16_BIT], runner->denorm_mode, source, &blob);
} }
else else
{ {

View File

@@ -304,6 +304,8 @@ struct shader_runner
float luminance_scale, luminance_offset; float luminance_scale, luminance_offset;
} bump[8]; } bump[8];
enum denorm_mode denorm_mode;
struct viewport viewports[4]; struct viewport viewports[4];
unsigned int viewport_count; unsigned int viewport_count;

View File

@@ -591,8 +591,16 @@ static inline HRESULT vkd3d_shader_code_from_dxc_blob(IDxcBlob *blob, struct vkd
return S_OK; return S_OK;
} }
static inline HRESULT dxc_compile(void *dxc_compiler, const WCHAR *profile, enum denorm_mode
unsigned int compile_options, bool enable_16bit_types, const char *hlsl, struct vkd3d_shader_code *blob_out) {
DENORM_NOT_SPECIFIED = 0,
DENORM_PRESERVE,
DENORM_FTZ,
DENORM_ANY,
};
static inline HRESULT dxc_compile(void *dxc_compiler, const WCHAR *profile, unsigned int compile_options,
bool enable_16bit_types, enum denorm_mode denorm_mode, const char *hlsl, struct vkd3d_shader_code *blob_out)
{ {
DxcBuffer src_buf = {hlsl, strlen(hlsl), 65001}; DxcBuffer src_buf = {hlsl, strlen(hlsl), 65001};
IDxcCompiler3 *compiler = dxc_compiler; IDxcCompiler3 *compiler = dxc_compiler;
@@ -615,11 +623,12 @@ static inline HRESULT dxc_compile(void *dxc_compiler, const WCHAR *profile,
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL,
}; };
memset(blob_out, 0, sizeof(*blob_out)); memset(blob_out, 0, sizeof(*blob_out));
arg_count = ARRAY_SIZE(args) - 4; arg_count = ARRAY_SIZE(args) - 5;
if (compile_options & D3DCOMPILE_PACK_MATRIX_ROW_MAJOR) if (compile_options & D3DCOMPILE_PACK_MATRIX_ROW_MAJOR)
args[arg_count++] = L"/Zpr"; args[arg_count++] = L"/Zpr";
if (compile_options & D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR) if (compile_options & D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR)
@@ -629,6 +638,24 @@ static inline HRESULT dxc_compile(void *dxc_compiler, const WCHAR *profile,
if (enable_16bit_types) if (enable_16bit_types)
args[arg_count++] = L"/enable-16bit-types"; args[arg_count++] = L"/enable-16bit-types";
switch (denorm_mode)
{
case DENORM_NOT_SPECIFIED:
break;
case DENORM_PRESERVE:
args[arg_count++] = L"/denorm preserve";
break;
case DENORM_FTZ:
args[arg_count++] = L"/denorm ftz";
break;
case DENORM_ANY:
args[arg_count++] = L"/denorm any";
break;
}
if (FAILED(hr = IDxcCompiler3_Compile(compiler, &src_buf, args, if (FAILED(hr = IDxcCompiler3_Compile(compiler, &src_buf, args,
arg_count, NULL, &IID_IDxcResult, (void **)&result))) arg_count, NULL, &IID_IDxcResult, (void **)&result)))
return hr; return hr;

View File

@@ -944,7 +944,8 @@ static void test_scan_signatures(void)
{ {
vkd3d_test_push_context("test %u", i); vkd3d_test_push_context("test %u", i);
rc = dxc_compile(compiler, dxil_tests[i].profile, 0, dxil_tests[i].enable_16bit, dxil_tests[i].source, &dxbc); rc = dxc_compile(compiler, dxil_tests[i].profile, 0, dxil_tests[i].enable_16bit,
DENORM_NOT_SPECIFIED, dxil_tests[i].source, &dxbc);
ok(rc == S_OK, "Got rc %#x.\n", rc); ok(rc == S_OK, "Got rc %#x.\n", rc);
compile_info.next = &signature_info; compile_info.next = &signature_info;