vkd3d-shader/ir: Implement exponential fog.

This commit is contained in:
Elizabeth Figura
2024-11-13 19:39:35 -06:00
committed by Henri Verbeet
parent 1fbbc82f3a
commit d56601c8d0
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
7 changed files with 142 additions and 11 deletions

View File

@@ -78,6 +78,20 @@ 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
fog exp ortho 2.0
draw triangle strip 4
probe (160, 120) rgba (0.0, 0.45118836, 1.0, 1.0) 64
probe (480, 360) rgba (0.0, 0.63212056, 1.0, 1.0) 64
probe (160, 120) rgba (0.0, 0.45118836, 1.0, 1.0) 64
probe (480, 360) rgba (0.0, 0.63212056, 1.0, 1.0) 64
fog exp2 ortho 2.0
draw triangle strip 4
probe (160, 120) rgba (0.0, 0.30232367, 1.0, 1.0) 64
probe (480, 360) rgba (0.0, 0.63212056, 1.0, 1.0) 64
probe (160, 120) rgba (0.0, 0.30232367, 1.0, 1.0) 64
probe (480, 360) rgba (0.0, 0.63212056, 1.0, 1.0) 64
% Test a VS that doesn't write fog, but does write specular.

View File

@@ -1450,6 +1450,11 @@ static void parse_test_directive(struct shader_runner *runner, const char *line)
if (sscanf(line, "%f %f", &runner->fog_start, &runner->fog_end) < 2)
fatal_error("Malformed fog constants '%s'.\n", line);
}
else if (runner->fog_mode == FOG_MODE_EXP || runner->fog_mode == FOG_MODE_EXP2)
{
if (sscanf(line, "%f", &runner->fog_density) < 1)
fatal_error("Malformed fog constants '%s'.\n", line);
}
}
else if (match_string(line, "fog-colour", &line))
{
@@ -1909,6 +1914,7 @@ void run_shader_tests(struct shader_runner *runner, const struct shader_runner_c
runner->fog_mode = FOG_MODE_DISABLE;
runner->fog_start = 0.0f;
runner->fog_end = 1.0f;
runner->fog_density = 1.0f;
runner->sample_mask = ~0u;
runner->depth_bounds = false;

View File

@@ -234,7 +234,7 @@ struct shader_runner
bool point_sprite;
struct vec4 fog_colour;
enum fog_mode fog_mode;
float fog_start, fog_end;
float fog_start, fog_end, fog_density;
bool ortho_fog;
};

View File

@@ -522,6 +522,8 @@ static bool d3d9_runner_draw(struct shader_runner *r,
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_SetRenderState(device, D3DRS_FOGDENSITY, float_to_int(runner->r.fog_density));
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

@@ -30,6 +30,9 @@
#include "vulkan_utils.h"
#include "vkd3d_test.h"
#define LOG2_E 1.44269504f
#define SQRT_LOG2_E 1.20112241f
struct vulkan_resource
{
struct resource r;
@@ -274,6 +277,8 @@ 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;
case FOG_MODE_EXP: return VKD3D_SHADER_FOG_FRAGMENT_EXP;
case FOG_MODE_EXP2: return VKD3D_SHADER_FOG_FRAGMENT_EXP2;
default: fatal_error("Unhandled fog mode %#x.\n", mode);
}
}
@@ -510,15 +515,28 @@ static bool compile_d3d_code(struct vulkan_shader_runner *runner,
parameters[20].type = VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT;
parameters[20].data_type = VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32;
if (runner->r.fog_mode == FOG_MODE_NONE)
switch (runner->r.fog_mode)
{
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);
case FOG_MODE_NONE:
parameters[19].u.immediate_constant.u.f32 = 0.0f;
parameters[20].u.immediate_constant.u.f32 = -1.0f;
break;
case FOG_MODE_LINEAR:
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);
break;
case FOG_MODE_EXP:
parameters[20].u.immediate_constant.u.f32 = runner->r.fog_density * LOG2_E;
break;
case FOG_MODE_EXP2:
parameters[20].u.immediate_constant.u.f32 = runner->r.fog_density * SQRT_LOG2_E;
break;
case FOG_MODE_DISABLE:
break;
}
parameters[21].name = VKD3D_SHADER_PARAMETER_NAME_FOG_SOURCE;