summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorAxel Davy <[email protected]>2018-08-16 16:29:31 +0200
committerAxel Davy <[email protected]>2018-09-25 22:05:24 +0200
commita9bf82ecf4c284989c40e4e6c1f6962bc9bd58d2 (patch)
tree895f130102eca8aba74c566ac15d6a10ed760297 /src/gallium
parent7ee5e5e239a5528c6eed2d1bb47b48434de74a6e (diff)
st/nine: Use perspective correction for ps depth fog
Emulate perspective interpolation of depth for programmable ps fog ff ps fog uses position z, or 1/w depending on the ff projection matrix set. This is according to public documents found describing the algorithm and tests we made. In the case of programmable ps, we used position's z, which was sufficient to pass wine tests (which test shaders don't set w). Issue https://github.com/iXit/Mesa-3D/issues/315 showed that this calculation was wrong. Using perspective interpolation on z, that is using z * 1/w seems to satisfy both this application and wine tests. Fixes: https://github.com/iXit/Mesa-3D/issues/315 Signed-off-by: Axel Davy <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/state_trackers/nine/nine_shader.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/src/gallium/state_trackers/nine/nine_shader.c b/src/gallium/state_trackers/nine/nine_shader.c
index 5b8ad3f161e..913508fb889 100644
--- a/src/gallium/state_trackers/nine/nine_shader.c
+++ b/src/gallium/state_trackers/nine/nine_shader.c
@@ -3458,8 +3458,8 @@ shader_add_ps_fog_stage(struct shader_translator *tx, struct ureg_src src_col)
struct ureg_program *ureg = tx->ureg;
struct ureg_dst oCol0 = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
struct ureg_src fog_end, fog_coeff, fog_density;
- struct ureg_src fog_vs, depth, fog_color;
- struct ureg_dst fog_factor;
+ struct ureg_src fog_vs, fog_color;
+ struct ureg_dst fog_factor, depth;
if (!tx->info->fog_enable) {
ureg_MOV(ureg, oCol0, src_col);
@@ -3467,8 +3467,10 @@ shader_add_ps_fog_stage(struct shader_translator *tx, struct ureg_src src_col)
}
if (tx->info->fog_mode != D3DFOG_NONE) {
- depth = nine_get_position_input(tx);
- depth = ureg_scalar(depth, TGSI_SWIZZLE_Z);
+ depth = tx_scratch_scalar(tx);
+ /* Depth used for fog is perspective interpolated */
+ ureg_RCP(ureg, depth, ureg_scalar(nine_get_position_input(tx), TGSI_SWIZZLE_W));
+ ureg_MUL(ureg, depth, ureg_src(depth), ureg_scalar(nine_get_position_input(tx), TGSI_SWIZZLE_Z));
}
nine_info_mark_const_f_used(tx->info, 33);
@@ -3478,16 +3480,16 @@ shader_add_ps_fog_stage(struct shader_translator *tx, struct ureg_src src_col)
if (tx->info->fog_mode == D3DFOG_LINEAR) {
fog_end = NINE_CONSTANT_SRC_SWIZZLE(33, X);
fog_coeff = NINE_CONSTANT_SRC_SWIZZLE(33, Y);
- ureg_ADD(ureg, fog_factor, fog_end, ureg_negate(depth));
+ ureg_ADD(ureg, fog_factor, fog_end, ureg_negate(ureg_src(depth)));
ureg_MUL(ureg, ureg_saturate(fog_factor), tx_src_scalar(fog_factor), fog_coeff);
} else if (tx->info->fog_mode == D3DFOG_EXP) {
fog_density = NINE_CONSTANT_SRC_SWIZZLE(33, X);
- ureg_MUL(ureg, fog_factor, depth, fog_density);
+ ureg_MUL(ureg, fog_factor, ureg_src(depth), fog_density);
ureg_MUL(ureg, fog_factor, tx_src_scalar(fog_factor), ureg_imm1f(ureg, -1.442695f));
ureg_EX2(ureg, fog_factor, tx_src_scalar(fog_factor));
} else if (tx->info->fog_mode == D3DFOG_EXP2) {
fog_density = NINE_CONSTANT_SRC_SWIZZLE(33, X);
- ureg_MUL(ureg, fog_factor, depth, fog_density);
+ ureg_MUL(ureg, fog_factor, ureg_src(depth), fog_density);
ureg_MUL(ureg, fog_factor, tx_src_scalar(fog_factor), tx_src_scalar(fog_factor));
ureg_MUL(ureg, fog_factor, tx_src_scalar(fog_factor), ureg_imm1f(ureg, -1.442695f));
ureg_EX2(ureg, fog_factor, tx_src_scalar(fog_factor));