Paul Gofman : d3dx9: Get rid of constant' s length checking for matrix in set_constants().

Alexandre Julliard julliard at winehq.org
Tue Jun 27 17:19:08 CDT 2017


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

Author: Paul Gofman <gofmanp at gmail.com>
Date:   Thu Jun 22 16:11:55 2017 +0300

d3dx9: Get rid of constant's length checking for matrix in set_constants().

When count in const_upload_info is calculated precisely (considering actual
constant set length), boolean matrix setting fall in direct copy path, unless
transpose is required. The case of incomplete last row for matrix should be
handled in set_constants() for transposed boolean constant only.

Signed-off-by: Paul Gofman <gofmanp at gmail.com>
Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/d3dx9_36/preshader.c | 46 ++++++++++++++++++++++++++++++++++++----------
 1 file changed, 36 insertions(+), 10 deletions(-)

diff --git a/dlls/d3dx9_36/preshader.c b/dlls/d3dx9_36/preshader.c
index 3b06f66..25374a3 100644
--- a/dlls/d3dx9_36/preshader.c
+++ b/dlls/d3dx9_36/preshader.c
@@ -269,6 +269,7 @@ struct const_upload_info
     unsigned int major_stride;
     unsigned int major_count;
     unsigned int count;
+    unsigned int minor_remainder;
 };
 
 static enum pres_value_type table_type_from_param_type(D3DXPARAMETER_TYPE type)
@@ -1038,10 +1039,22 @@ static void get_const_upload_info(struct d3dx_const_param_eval_output *const_set
         info->major = param->rows;
         info->minor = param->columns;
     }
-    info->major_stride = max(info->minor, get_reg_components(table));
-    info->major_count = min(info->major * info->major_stride,
-            get_offset_reg(table, const_set->register_count) + info->major_stride - 1) / info->major_stride;
-    info->count = info->major_count * info->minor;
+
+    if (get_reg_components(table) == 1)
+    {
+        unsigned int const_length = get_offset_reg(table, const_set->register_count);
+
+        info->major_stride = info->minor;
+        info->major_count = const_length / info->major_stride;
+        info->minor_remainder = const_length % info->major_stride;
+    }
+    else
+    {
+        info->major_stride = get_reg_components(table);
+        info->major_count = const_set->register_count;
+        info->minor_remainder = 0;
+    }
+    info->count = info->major_count * info->minor + info->minor_remainder;
 }
 
 static void pres_int_from_float(void *out, const void *in, unsigned int count)
@@ -1172,16 +1185,19 @@ static void set_constants(struct d3dx_regstore *rs, struct d3dx_const_tab *const
             {
                 for (j = 0; j < info.minor; ++j)
                 {
-                    unsigned int offset;
-
-                    offset = i * info.major_stride + j;
-                    if (get_reg_offset(table, offset) >= const_set->register_count)
-                        break;
                     if (info.transpose)
                         param_offset = i + j * info.major;
                     else
                         param_offset = i * info.minor + j;
-                    out[offset] = data[param_offset];
+                    out[i * info.major_stride + j] = data[param_offset];
+                }
+            }
+            if (info.transpose)
+            {
+                for (j = 0; j < info.minor_remainder; ++j)
+                {
+                    param_offset = i + j * info.major;
+                    out[i * info.major_stride + j] = data[param_offset];
                 }
             }
             start_offset += get_offset_reg(table, const_set->register_count);
@@ -1417,6 +1433,16 @@ static HRESULT init_set_constants_param(struct d3dx_const_tab *const_tab, ID3DXC
             && !info.transpose && info.minor == info.major_stride
             && info.count == get_offset_reg(const_set.table, const_set.register_count)
             && info.count * sizeof(unsigned int) <= param->bytes;
+    if (info.minor_remainder && !const_set.direct_copy && !info.transpose)
+        FIXME("Incomplete last row for not transposed matrix which cannot be directly copied, parameter %s.\n",
+                debugstr_a(param->name));
+
+    if (info.major_count > info.major
+            || (info.major_count == info.major && info.minor_remainder))
+    {
+        WARN("Constant dimensions exceed parameter size.\n");
+        return D3DERR_INVALIDCALL;
+    }
 
     if (FAILED(hr = append_const_set(const_tab, &const_set)))
         return hr;




More information about the wine-cvs mailing list