Module: wine
Branch: master
Commit: c7c785861af93448a22e3d6d6cab03a86ab7b5fc
URL: http://source.winehq.org/git/wine.git/?a=commit;h=c7c785861af93448a22e3d6d6…
Author: Stefan Dösinger <stefan(a)codeweavers.com>
Date: Fri Nov 2 01:11:15 2007 +0100
wined3d: Replace the position fixup mul-add-add with a MAD.
---
dlls/wined3d/directx.c | 1 +
dlls/wined3d/vertexshader.c | 30 ++++++++++++------------------
2 files changed, 13 insertions(+), 18 deletions(-)
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index ada76e2..9ccc47b 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -2642,6 +2642,7 @@ static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter,
} else {
object->surface_alignment = 4;
}
+ object->posFixup[0] = 1.0; /* This is needed to get the x coord unmodified through a MAD */
/* Set the state up as invalid until the device is fully created */
object->state = WINED3DERR_DRIVERINTERNALERROR;
diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c
index e49e34a..4e2a7c5 100644
--- a/dlls/wined3d/vertexshader.c
+++ b/dlls/wined3d/vertexshader.c
@@ -333,20 +333,16 @@ static VOID IWineD3DVertexShaderImpl_GenerateShader(
/* If this shader doesn't use fog copy the z coord to the fog coord so that we can use table fog */
if (!reg_maps->fog)
shader_addline(&buffer, "gl_FogFragCoord = gl_Position.z;\n");
-
+
/* Write the final position.
*
* OpenGL coordinates specify the center of the pixel while d3d coords specify
- * the corner. The offsets are stored in z and w in the 2nd row of the projection
- * matrix to avoid wasting a free shader constant. Add them to the w and z coord
- * of the 2nd row
- */
- shader_addline(&buffer, "gl_Position.x = gl_Position.x + posFixup[2];\n");
- shader_addline(&buffer, "gl_Position.y = gl_Position.y + posFixup[3];\n");
- /* Account for any inverted textures (render to texture case) by reversing the y coordinate
- * (this is handled in drawPrim() when it sets the MODELVIEW and PROJECTION matrices)
+ * the corner. The offsets are stored in z and w in posFixup. posFixup.y contains
+ * 1.0 or -1.0 to turn the rendering upside down for offscreen rendering. PosFixup.x
+ * contains 1.0 to allow a mad.
*/
- shader_addline(&buffer, "gl_Position.y = gl_Position.y * posFixup[1];\n");
+ shader_addline(&buffer, "gl_Position.xy = gl_Position.xy * posFixup.xy + posFixup.zw;\n");
+
/* Z coord [0;1]->[-1;1] mapping, see comment in transform_projection in state.c
*
* Basically we want(in homogenous coordinates) z = z * 2 - 1. However, shaders are run
@@ -399,15 +395,13 @@ static VOID IWineD3DVertexShaderImpl_GenerateShader(
/* Write the final position.
*
* OpenGL coordinates specify the center of the pixel while d3d coords specify
- * the corner. The offsets are stored in the 2nd row of the projection matrix,
- * the x offset in z and the y offset in w. Add them to the resulting position
- */
- shader_addline(&buffer, "ADD TMP_OUT.x, TMP_OUT.x, posFixup.z;\n");
- shader_addline(&buffer, "ADD TMP_OUT.y, TMP_OUT.y, posFixup.w;\n");
- /* Account for any inverted textures (render to texture case) by reversing the y coordinate
- * (this is handled in drawPrim() when it sets the MODELVIEW and PROJECTION matrices)
+ * the corner. The offsets are stored in z and w in posFixup. posFixup.y contains
+ * 1.0 or -1.0 to turn the rendering upside down for offscreen rendering. PosFixup.x
+ * contains 1.0 to allow a mad, but arb vs swizzles are too restricted for that.
*/
- shader_addline(&buffer, "MUL TMP_OUT.y, TMP_OUT.y, posFixup.y;\n");
+ shader_addline(&buffer, "ADD TMP_OUT.x, TMP_OUT.x, posFixup.z;");
+ shader_addline(&buffer, "MAD TMP_OUT.y, TMP_OUT.y, posFixup.y, posFixup.w;");
+
/* Z coord [0;1]->[-1;1] mapping, see comment in transform_projection in state.c
* and the glsl equivalent
*/
Module: wine
Branch: master
Commit: 468309e055b5e14f6da919b173eb199954b65ef1
URL: http://source.winehq.org/git/wine.git/?a=commit;h=468309e055b5e14f6da919b17…
Author: Stefan Dösinger <stefan(a)codeweavers.com>
Date: Sun Oct 28 21:21:24 2007 +0100
wined3d: Get rid of the conditionals in the glsl lit implementation.
---
dlls/wined3d/glsl_shader.c | 25 +++++++++++++++++++++++--
1 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 98cbcf8..c2da059 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -1777,8 +1777,29 @@ void shader_glsl_lit(SHADER_OPCODE_ARG* arg) {
shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_1, &src1_param);
shader_glsl_add_src_param(arg, arg->src[0], arg->src_addr[0], WINED3DSP_WRITEMASK_3, &src3_param);
- shader_addline(arg->buffer, "vec4(1.0, (%s > 0.0 ? %s : 0.0), (%s > 0.0 ? ((%s > 0.0) ? pow(%s, clamp(%s, -128.0, 128.0)) : 0.0) : 0.0), 1.0)%s);\n",
- src0_param.param_str, src0_param.param_str, src0_param.param_str, src1_param.param_str, src1_param.param_str, src3_param.param_str, dst_mask);
+ /* The sdk specifies the instruction like this
+ * dst.x = 1.0;
+ * if(src.x > 0.0) dst.y = src.x
+ * else dst.y = 0.0.
+ * if(src.x > 0.0 && src.y > 0.0) dst.z = pow(src.y, power);
+ * else dst.z = 0.0;
+ * dst.w = 1.0;
+ *
+ * Obviously that has quite a few conditionals in it which we don't like. So the first step is this:
+ * dst.x = 1.0 ... No further explanation needed
+ * dst.y = max(src.y, 0.0); ... If x < 0.0, use 0.0, otherwise x. Same as the conditional
+ * dst.z = x > 0.0 ? pow(max(y, 0.0), p) : 0; ... 0 ^ power is 0, and otherwise we use y anyway
+ * dst.w = 1.0. ... Nothing fancy.
+ *
+ * So we still have one conditional in there. So do this:
+ * dst.z = pow(max(0.0, src.y) * step(0.0, src.x), power);
+ *
+ * step(0.0, x) will return 1 if src.x > 0.0, and 0 otherwise. So if y is 0 we get pow(0.0 * 1.0, power),
+ * which sets dst.z to 0. If y > 0, but x = 0.0, we get pow(y * 0.0, power), which results in 0 too.
+ * if both x and y are > 0, we get pow(y * 1.0, power), as it is supposed to
+ */
+ shader_addline(arg->buffer, "vec4(1.0, max(%s, 0.0), pow(max(0.0, %s) * step(0.0, %s), clamp(%s, -128.0, 128.0)), 1.0)%s);\n",
+ src0_param.param_str, src1_param.param_str, src0_param.param_str, src3_param.param_str, dst_mask);
}
/** Process the WINED3DSIO_DST instruction in GLSL: