vkd3d-shader/ir: Allow controlling the fog source through a parameter.

This commit is contained in:
Elizabeth Figura
2024-11-13 19:16:39 -06:00
committed by Henri Verbeet
parent fc98cb482f
commit 1fbbc82f3a
Notes: Henri Verbeet 2024-12-02 17:19:05 +01:00
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1265
9 changed files with 351 additions and 1 deletions

View File

@@ -70,3 +70,66 @@ probe (160, 120) rgba (0.0, 0.8, 1.0, 1.0)
probe (480, 360) rgba (0.0, 0.8, 1.0, 1.0)
probe (160, 120) rgba (0.0, 0.8, 1.0, 1.0)
probe (480, 360) rgba (0.0, 0.8, 1.0, 1.0)
fog linear ortho 0.1 1.1
draw triangle strip 4
probe (160, 120) rgba (0.0, 0.2, 1.0, 1.0) 64
probe (480, 360) rgba (0.0, 0.4, 1.0, 1.0) 64
probe (160, 120) rgba (0.0, 0.2, 1.0, 1.0) 64
probe (480, 360) rgba (0.0, 0.4, 1.0, 1.0) 64
% Test a VS that doesn't write fog, but does write specular.
[vertex shader]
float4 main(float4 pos : position, out float4 specular : color1) : sv_position
{
specular = float4(0, 0, 0, 0.3);
return pos;
}
[test]
fog none
draw triangle strip 4
probe (160, 120) rgba (0.0, 0.7, 1.0, 1.0)
probe (480, 360) rgba (0.0, 0.7, 1.0, 1.0)
probe (160, 120) rgba (0.0, 0.7, 1.0, 1.0)
probe (480, 360) rgba (0.0, 0.7, 1.0, 1.0)
fog linear ortho 0.1 1.1
draw triangle strip 4
probe (160, 120) rgba (0.0, 0.2, 1.0, 1.0) 64
probe (480, 360) rgba (0.0, 0.4, 1.0, 1.0) 64
probe (160, 120) rgba (0.0, 0.2, 1.0, 1.0) 64
probe (480, 360) rgba (0.0, 0.4, 1.0, 1.0) 64
% Test the non-orthogonal case, where fog comes from W.
% We don't do this using the same VB: drivers disagree on whether Z means vertex
% Z or pixel Z (i.e. whether perspective division is applied, as well as things
% like depth bias) so we want W to be flat 1.0 for the Z tests.
[vb 0]
-2.0 0.0 0.2 0.5
0.0 2.0 0.2 0.5
0.0 0.0 0.2 0.5
0.0 0.0 0.2 0.9
0.0 2.0 0.2 0.9
2.0 0.0 0.2 0.9
0.0 -2.0 0.5 0.5
-2.0 0.0 0.5 0.5
0.0 0.0 0.5 0.5
0.0 -2.0 0.5 0.9
0.0 0.0 0.5 0.9
2.0 0.0 0.5 0.9
[test]
fog linear non-ortho 0.1 1.1
draw triangle list 12
probe (300, 220) rgba (0.0, 0.4, 1.0, 1.0) 64
probe (340, 220) rgba (0.0, 0.8, 1.0, 1.0) 64
probe (300, 260) rgba (0.0, 0.4, 1.0, 1.0) 64
probe (340, 260) rgba (0.0, 0.8, 1.0, 1.0) 64

View File

@@ -1439,6 +1439,17 @@ static void parse_test_directive(struct shader_runner *runner, const char *line)
runner->fog_mode = FOG_MODE_EXP2;
else
fatal_error("Invalid fog mode '%s'.\n", line);
if (match_string(line, "ortho", &line))
runner->ortho_fog = true;
if (match_string(line, "non-ortho", &line))
runner->ortho_fog = false;
if (runner->fog_mode == FOG_MODE_LINEAR)
{
if (sscanf(line, "%f %f", &runner->fog_start, &runner->fog_end) < 2)
fatal_error("Malformed fog constants '%s'.\n", line);
}
}
else if (match_string(line, "fog-colour", &line))
{
@@ -1896,6 +1907,8 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_c
runner->point_size_min = 1.0f;
runner->point_size_max = FLT_MAX;
runner->fog_mode = FOG_MODE_DISABLE;
runner->fog_start = 0.0f;
runner->fog_end = 1.0f;
runner->sample_mask = ~0u;
runner->depth_bounds = false;

View File

@@ -234,6 +234,8 @@ struct shader_runner
bool point_sprite;
struct vec4 fog_colour;
enum fog_mode fog_mode;
float fog_start, fog_end;
bool ortho_fog;
};
struct shader_runner_ops

View File

@@ -354,6 +354,7 @@ static bool d3d9_runner_draw(struct shader_runner *r,
ID3D10Blob *vs_code, *ps_code;
IDirect3DVertexShader9 *vs;
IDirect3DPixelShader9 *ps;
D3DMATRIX proj_matrix;
HRESULT hr;
if (instance_count > 1)
@@ -509,8 +510,18 @@ static bool d3d9_runner_draw(struct shader_runner *r,
hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGTABLEMODE, runner->r.fog_mode);
ok(hr == D3D_OK, "Failed to set render state, hr %#lx.\n", hr);
}
memset(&proj_matrix, 0, sizeof(proj_matrix));
proj_matrix._11 = proj_matrix._22 = proj_matrix._33 = proj_matrix._44 = 1.0f;
if (!runner->r.ortho_fog)
proj_matrix._44 = 1.01f;
hr = IDirect3DDevice9_SetTransform(device, D3DTS_PROJECTION, &proj_matrix);
ok(hr == D3D_OK, "Failed to set projection matrix, hr %#lx.\n", hr);
hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGCOLOR, d3d_color_from_vec4(&runner->r.fog_colour));
ok(hr == D3D_OK, "Failed to set render state, hr %#lx.\n", hr);
hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGSTART, float_to_int(runner->r.fog_start));
ok(hr == D3D_OK, "Failed to set render state, hr %#lx.\n", hr);
hr = IDirect3DDevice9_SetRenderState(device, D3DRS_FOGEND, float_to_int(runner->r.fog_end));
ok(hr == D3D_OK, "Failed to set render state, hr %#lx.\n", hr);
hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &vertex_declaration);
ok(hr == D3D_OK, "Failed to create vertex declaration, hr %#lx.\n", hr);

View File

@@ -273,10 +273,21 @@ static enum vkd3d_shader_fog_fragment_mode get_fog_fragment_mode(enum fog_mode m
{
case FOG_MODE_DISABLE: return VKD3D_SHADER_FOG_FRAGMENT_NONE;
case FOG_MODE_NONE: return VKD3D_SHADER_FOG_FRAGMENT_LINEAR;
case FOG_MODE_LINEAR: return VKD3D_SHADER_FOG_FRAGMENT_LINEAR;
default: fatal_error("Unhandled fog mode %#x.\n", mode);
}
}
static enum vkd3d_shader_fog_source get_fog_source(const struct shader_runner *runner)
{
if (runner->fog_mode == FOG_MODE_DISABLE)
return VKD3D_SHADER_FOG_SOURCE_FOG;
else if (runner->fog_mode == FOG_MODE_NONE)
return VKD3D_SHADER_FOG_SOURCE_FOG_OR_SPECULAR_W;
return runner->ortho_fog ? VKD3D_SHADER_FOG_SOURCE_Z : VKD3D_SHADER_FOG_SOURCE_W;
}
static bool compile_hlsl_and_scan(struct vulkan_shader_runner *runner, enum shader_type type)
{
struct vkd3d_shader_parameter_info parameter_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_PARAMETER_INFO};
@@ -327,7 +338,7 @@ static bool compile_d3d_code(struct vulkan_shader_runner *runner,
struct vkd3d_shader_varying_map varying_map[12];
struct vkd3d_shader_resource_binding *binding;
struct vkd3d_shader_compile_option options[2];
struct vkd3d_shader_parameter1 parameters[21];
struct vkd3d_shader_parameter1 parameters[22];
unsigned int i;
char *messages;
int ret;
@@ -504,6 +515,16 @@ static bool compile_d3d_code(struct vulkan_shader_runner *runner,
parameters[19].u.immediate_constant.u.f32 = 0.0f;
parameters[20].u.immediate_constant.u.f32 = -1.0f;
}
else
{
parameters[19].u.immediate_constant.u.f32 = runner->r.fog_end;
parameters[20].u.immediate_constant.u.f32 = 1.0 / (runner->r.fog_end - runner->r.fog_start);
}
parameters[21].name = VKD3D_SHADER_PARAMETER_NAME_FOG_SOURCE;
parameters[21].type = VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT;
parameters[21].data_type = VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32;
parameters[21].u.immediate_constant.u.u32 = get_fog_source(&runner->r);
parameter_info.parameter_count = ARRAY_SIZE(parameters);
parameter_info.parameters = parameters;