=?UTF-8?Q?Rico=20Sch=C3=BCller=20?=: d3dx9: Add support for structs to ID3DXConstantTable.

Alexandre Julliard julliard at winehq.org
Sat Jul 27 13:23:35 CDT 2013


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

Author: Rico Schüller <kgbricola at web.de>
Date:   Wed Jul 24 22:30:21 2013 +0200

d3dx9: Add support for structs to ID3DXConstantTable.

---

 dlls/d3dx9_36/shader.c |   79 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 77 insertions(+), 2 deletions(-)

diff --git a/dlls/d3dx9_36/shader.c b/dlls/d3dx9_36/shader.c
index d44316f..15dbb7a 100644
--- a/dlls/d3dx9_36/shader.c
+++ b/dlls/d3dx9_36/shader.c
@@ -958,8 +958,83 @@ static UINT set(struct ID3DXConstantTableImpl *table, IDirect3DDevice9 *device,
     /* D3DXPC_STRUCT is somewhat special */
     if (desc->Class == D3DXPC_STRUCT)
     {
-        FIXME("Structs are not supported, yet.\n");
-        return 0;
+        /*
+         * Struct array sets the last complete input to the first struct element, all other
+         * elements are not set.
+         * E.g.: struct {int i;} s1[2];
+         *       SetValue(device, "s1", [1, 2], 8) => s1 = {2, x};
+         *
+         *       struct {int i; int n} s2[2];
+         *       SetValue(device, "s2", [1, 2, 3, 4, 5], 20) => s1 = {{3, 4}, {x, x}};
+         */
+        if (desc->Elements > 1)
+        {
+            UINT offset = *size / (desc->Rows * desc->Columns) - 1;
+
+            offset = min(desc->Elements - 1, offset);
+            last = offset * desc->Rows * desc->Columns;
+
+            if ((is_pointer || (!is_pointer && inclass == D3DXPC_MATRIX_ROWS)) && desc->RegisterSet != D3DXRS_BOOL)
+            {
+                set(table, device, &constant->constants[0], NULL, intype, size, incol, inclass, 0, is_pointer);
+            }
+            else
+            {
+                last += set(table, device, &constant->constants[0], indata, intype, size, incol, inclass,
+                        index + last, is_pointer);
+            }
+        }
+        else
+        {
+            /*
+             * D3DXRS_BOOL is always set. As there are only 16 bools and there are
+             * exactly 16 input values, use matrix transpose.
+             */
+            if (inclass == D3DXPC_MATRIX_ROWS && desc->RegisterSet == D3DXRS_BOOL)
+            {
+                D3DXMATRIX mat, *m, min;
+                D3DXMatrixTranspose(&mat, &min);
+
+                if (is_pointer)
+                    min = *(D3DXMATRIX *)(indata[index / 16]);
+                else
+                    min = **(D3DXMATRIX **)indata;
+
+                D3DXMatrixTranspose(&mat, &min);
+                m = &mat;
+                for (i = 0; i < desc->StructMembers; ++i)
+                {
+                    last += set(table, device, &constant->constants[i], (const void **)&m, intype, size, incol,
+                            D3DXPC_SCALAR, index + last, is_pointer);
+                }
+            }
+            /*
+             * For pointers or for matrix rows, only the first member is set.
+             * All other members are set to 0. This is not true for D3DXRS_BOOL.
+             * E.g.: struct {int i; int n} s;
+             *       SetValue(device, "s", [1, 2], 8) => s = {1, 0};
+             */
+            else if ((is_pointer || (!is_pointer && inclass == D3DXPC_MATRIX_ROWS)) && desc->RegisterSet != D3DXRS_BOOL)
+            {
+                last = set(table, device, &constant->constants[0], indata, intype, size, incol, inclass,
+                        index + last, is_pointer);
+
+                for (i = 1; i < desc->StructMembers; ++i)
+                {
+                    set(table, device, &constant->constants[i], NULL, intype, size, incol, inclass, 0, is_pointer);
+                }
+            }
+            else
+            {
+                for (i = 0; i < desc->StructMembers; ++i)
+                {
+                    last += set(table, device, &constant->constants[i], indata, intype, size, incol, D3DXPC_SCALAR,
+                            index + last, is_pointer);
+                }
+            }
+        }
+
+        return last;
     }
 
     /* elements */




More information about the wine-cvs mailing list