Stefan Dösinger : wined3d: Implement mova rounding in arb.

Alexandre Julliard julliard at winehq.org
Wed May 20 08:29:33 CDT 2009


Module: wine
Branch: master
Commit: c7ca3793cc7750588fc8232c332e99759b541a40
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=c7ca3793cc7750588fc8232c332e99759b541a40

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Thu May  7 19:12:07 2009 +0200

wined3d: Implement mova rounding in arb.

---

 dlls/wined3d/arb_program_shader.c |   56 ++++++++++++++++++++++++++++--------
 dlls/wined3d/baseshader.c         |    4 ++
 dlls/wined3d/wined3d_private.h    |    2 +-
 3 files changed, 48 insertions(+), 14 deletions(-)

diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index d5136bb..ecb6f0b 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -42,6 +42,13 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d);
 #define GLINFO_LOCATION      (*gl_info)
 
 /* GL locking for state handlers is done by the caller. */
+static BOOL need_mova_const(IWineD3DBaseShader *shader, const WineD3D_GL_Info *gl_info) {
+    IWineD3DBaseShaderImpl *This = (IWineD3DBaseShaderImpl *) shader;
+    if(!This->baseShader.reg_maps.usesmova) return FALSE;
+    /* TODO: ARR from GL_NV_vertex_program2_option */
+    return TRUE;
+}
+
 static BOOL need_helper_const(const WineD3D_GL_Info *gl_info) {
     if(!GL_SUPPORT(NV_VERTEX_PROGRAM)   || /* Need to init colors */
        gl_info->arb_vs_offset_limit     || /* Have to init texcoords */
@@ -51,12 +58,14 @@ static BOOL need_helper_const(const WineD3D_GL_Info *gl_info) {
     return FALSE;
 }
 
-static unsigned int reserved_vs_const(const WineD3D_GL_Info *gl_info) {
+static unsigned int reserved_vs_const(IWineD3DBaseShader *shader, const WineD3D_GL_Info *gl_info) {
+    unsigned int ret = 1;
     /* We use one PARAM for the pos fixup, and in some cases one to load
      * some immediate values into the shader
      */
-    if(need_helper_const(gl_info)) return 2;
-    else return 1;
+    if(need_helper_const(gl_info)) ret++;
+    if(need_mova_const(shader, gl_info)) ret++;
+    return ret;
 }
 
 /* Internally used shader constants. Applications can use constants 0 to GL_LIMITS(vshader_constantsF) - 1,
@@ -328,7 +337,7 @@ static void shader_generate_arb_declarations(IWineD3DBaseShader *iface, const sh
         max_constantsF = GL_LIMITS(pshader_constantsF);
     } else {
         if(This->baseShader.reg_maps.usesrelconstF) {
-            max_constantsF = GL_LIMITS(vshader_constantsF) - reserved_vs_const(gl_info);
+            max_constantsF = GL_LIMITS(vshader_constantsF) - reserved_vs_const(iface, gl_info);
         } else {
             max_constantsF = GL_LIMITS(vshader_constantsF) - 1;
         }
@@ -998,17 +1007,35 @@ static void shader_hw_mov(const struct wined3d_shader_instruction *ins)
 {
     IWineD3DBaseShaderImpl *shader = (IWineD3DBaseShaderImpl *)ins->ctx->shader;
 
-    if ((ins->ctx->reg_maps->shader_version.major == 1
-            && !shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type)
-            && ins->dst[0].reg.type == WINED3DSPR_ADDR)
-            || ins->handler_idx == WINED3DSIH_MOVA)
-    {
-        SHADER_BUFFER *buffer = ins->ctx->buffer;
-        char src0_param[256];
+    SHADER_BUFFER *buffer = ins->ctx->buffer;
+    char src0_param[256];
 
-        if (ins->handler_idx == WINED3DSIH_MOVA)
-            FIXME("mova should round\n");
+    if(ins->handler_idx == WINED3DSIH_MOVA) {
+        struct wined3d_shader_src_param tmp_src = ins->src[0];
+        tmp_src.swizzle = (tmp_src.swizzle & 0x3) * 0x55;
+        shader_arb_get_src_param(ins, &tmp_src, 0, src0_param);
 
+        /* This implements the mova formula used in GLSL. The first two instructions
+         * prepare the sign() part. Note that it is fine to have my_sign(0.0) = 1.0
+         * in this case:
+         * mova A0.x, 0.0
+         *
+         * A0.x = arl(floor(abs(0.0) + 0.5) * 1.0) = floor(0.5) = 0.0 since arl does a floor
+         *
+         * TODO: ARR from GL_NV_vertex_program2_option
+         */
+        shader_addline(buffer, "SGE TA.y, %s, mova_const.y;\n", src0_param);
+        shader_addline(buffer, "MAD TA.y, TA.y, mova_const.z, -mova_const.w;\n");
+
+        shader_addline(buffer, "ABS TA.x, %s;\n", src0_param);
+        shader_addline(buffer, "ADD TA.x, TA.x, mova_const.x;\n");
+        shader_addline(buffer, "FLR TA.x, TA.x;\n");
+        shader_addline(buffer, "MUL TA.x, TA.x, TA.y;\n");
+        shader_addline(buffer, "ARL A0.x, TA.x;\n");
+    } else if (ins->ctx->reg_maps->shader_version.major == 1
+          && !shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type)
+          && ins->dst[0].reg.type == WINED3DSPR_ADDR)
+    {
         src0_param[0] = '\0';
         if (((IWineD3DVertexShaderImpl *)shader)->rel_offset)
         {
@@ -2010,6 +2037,9 @@ static GLuint shader_arb_generate_vshader(IWineD3DVertexShader *iface,
     if(need_helper_const(gl_info)) {
         shader_addline(buffer, "PARAM helper_const = { 2.0, -1.0, %d.0, 0.0 };\n", This->rel_offset);
     }
+    if(need_mova_const((IWineD3DBaseShader *) iface, gl_info)) {
+        shader_addline(buffer, "PARAM mova_const = { 0.5, 0.0, 2.0, 1.0 };\n");
+    }
 
     /* Mesa supports only 95 constants */
     if (GL_VEND(MESA) || GL_VEND(WINE))
diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c
index 1746917..cf8171b 100644
--- a/dlls/wined3d/baseshader.c
+++ b/dlls/wined3d/baseshader.c
@@ -611,6 +611,10 @@ HRESULT shader_get_registers_used(IWineD3DBaseShader *iface, const struct wined3
             {
                 reg_maps->usestexldd = 1;
             }
+            else if(ins.handler_idx == WINED3DSIH_MOVA)
+            {
+                reg_maps->usesmova = 1;
+            }
 
             limit = ins.src_count + (ins.predicate ? 1 : 0);
             for (i = 0; i < limit; ++i)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index a0dcddb..526ba24 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -632,7 +632,7 @@ typedef struct shader_reg_maps
 
     WINED3DSAMPLER_TEXTURE_TYPE sampler_type[max(MAX_FRAGMENT_SAMPLERS, MAX_VERTEX_SAMPLERS)];
     BOOL bumpmat[MAX_TEXTURES], luminanceparams[MAX_TEXTURES];
-    char usesnrm, vpos, usesdsy, usestexldd;
+    char usesnrm, vpos, usesdsy, usestexldd, usesmova;
     char usesrelconstF;
 
     /* Whether or not loops are used in this shader, and nesting depth */




More information about the wine-cvs mailing list