mirror of
https://gitlab.winehq.org/wine/vkd3d.git
synced 2025-09-12 18:50:22 -07:00
vkd3d-shader/ir: Allow controlling the fog source through a parameter.
This commit is contained in:
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
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user