Re: [PATCH 4/5] d3dx9/tests: Add ID3DXConstantTable struct test.

2013-08-02 Thread Rico Schüller

On 31.07.2013 00:14, Matteo Bruni wrote:

2013/7/30 Rico Schüller kgbric...@web.de:

Hi Matteo,

please see the attached patch.


On 25.07.2013 16:13, Matteo Bruni wrote:


2013/7/24 Rico Schüller kgbric...@web.de:


---
   dlls/d3dx9_36/tests/shader.c | 308
+++
   1 file changed, 308 insertions(+)



This is okay, but as a followup can you add some tests with mixed-type
structs? Something like:

struct
{
  float f;
  int i;
  bool b;
};

If you have already written tests of this kind, I'd like to know what
does the compiler do in this case :)


Single variables could only have the tested types (I was not able to
generate other conversions than bool-bool, int-int, int-float,
bool-float, float-float). But I found a way to do it with structs and
there I found some issues. Hence this has to be fixed in wine, too. Thanks
for the nice question. :-)

Basically you got these for the struct:
1. D3DXRS_FLOAT4: if one variable is used as float or a float variable is
used or an int variable is used as bool (the compiler may do some
optimization), else #2
2. D3DXRS_BOOL: if a bool variable is used as bool (in an if clause), else
#3
3. D3DXRS_INT4

It looks like you could only do it that way with unused variables. I'm not
sure if this makes sense at all. Why would someone set an unused variable?
Maybe I missed something? Do you know anything else?



It does make some sense, although this is not what I expected. Also,
I'm getting different results...

If I understand correctly your test, all the fields of a structure
share the same registerset. Which is silly, since AFAIU each member of
the structure has a separate D3DXCONSTANT_DESC in the constant table,
both on disk and in memory, there is no point the compiler should
force the same registerset for all the struct members.
Yes, they share all the same registerset. The optimization seems to 
force only the type of the register (it optimizes the not used members out).



Under the constraint of forcing all the members in the same
registerset, the conversion rules you mention make sense. In SM3 an
if bool can be replaced by an if_comp with a float register and a
rep/loop, which is controlled by an integer constant, can be emulated
via loop unrolling (although I'm not sure how the compiler can
possibly do that for the shader in your testcase). These are also
pretty much the only use cases of bool and int constants and there are
no int or bool non-constant registers so essentially no other type
conversion is possible. You can check the plain text output from fxc
to see how those constants are used in the shader code and how did the
compiler manage to convert those constants from one type to another.

I tried to compile your HLSL shader myself (I had to disable
optimization though, otherwise compilation fails) and, assuming the
text output of fxc matches what actually ends up in the shader
bytecode, in general I'm getting different struct members in different
registersets. E.g. snbf gets allocated to c6-c9 and b8. FWIW, I used
fxc from the June 2010 DirectX SDK, on Windows 7.
I'm not sure why my results are different from yours. Or am I
misunderstanding the test?
The bytecode should match the result in the text output. Also after some 
additional test these structs seem to set several registers (as could be 
seen in the text), so the constant table constant desc is not able to 
give a full description for these. So an app should not depend on those 
or did I miss something? It's getting tricky again.

E.g.:
struct {float f2; int n2; bool b2;} snb;
sets:
D3DXRS_FLOAT4 15,16 (60-68)
D3DXRS_BOOL 3,4,5 (3-6)

I'll send an update to the tests to cover these issue. I think I have to 
look at the binary and whats really in there. Hopefully that information 
could be found somewhere ...


I'm also using the June 2010 SDK tools, but on wine. The problem might 
be, that fixme:d3d9:Direct3DShaderValidatorCreate9 stub will not fail 
here. If I disable optimization, I get (I think the same you got):

// Registers:
//
//   Name Reg   Size
//    - 
//   sb   b0   3
//   snb  b3   3
//   sbn  b6   2
//   sbnf b8   1
//   sn   c0   3
//   sbn  c3   3
//   sbnf c6   3
//   sbnf2c9   3
//   sbnf3c12  3
//   snb  c15  2

This is what I get (header.fx is the text file containing the shader) 
for the shader in the test without disabling anything:

wine fxc.exe /E main /Tvs_3_0 header.fx
// Registers:
//
//   Name Reg   Size
//    - 
//   sb   b0   3
//   snb  b3   3
//   sbn  b6   3
//   sbnf b9   2
//   sn   i0   3
//   sbnf3i3   3
//   sbnf2i6   2
//   sbnf c0   3
//   sbnf2c3   3
//   sbnf3c6   3

I'm using this receipt to generate the binary blob:

Re: [PATCH 4/5] d3dx9/tests: Add ID3DXConstantTable struct test.

2013-08-02 Thread Rico Schüller

On 01.08.2013 17:25, Matteo Bruni wrote:


Instead of generating an entry for the struct with the correct
members, the compiler generates TWO entries for sbnf, one with all its
fields in D3DXRS_FLOAT4 and the other with D3DXRS_BOOL. Which, if I'm
reading this correctly, makes 0 sense.
Calling GetConstantByName() on the various fields then happen to
return the first instance of the struct. It's the same with native
d3dx9, FWIW.


Yes, that's exactly the issue. The structs are in there two times with 
the same name. Maybe you could query the members somehow in a way we 
wouldn't expect it. At least you could query the struct constant by 
index instead of by name. After that you may get the correct member and 
set that single member. This may or may not set the other registers. 
That also needs a separate test case. What's broken is then only setting 
the whole struct. For now I think we should gather some information and 
add a fixme. As it is not possible to have two variables with the same 
name in the hlsl shader, what do you think about the attached patch? 
This way we would see apps use this tricky feature.




So this looks even more broken than we thought for struct constants.
You're right when you say that the application can't depend on this. I
assume that this means the application has to explicitly force each
field to a known location via the register keyword in the shader, or
(and this would be AWESOME) just blindly set the shader constants
which happened to be used by those fields in previous compilation of
the shader. Great...


Well the register theory needs also a test.


I'm also using the June 2010 SDK tools, but on wine. The problem might be,
that fixme:d3d9:Direct3DShaderValidatorCreate9 stub will not fail here. If
I disable optimization, I get (I think the same you got):
// Registers:
//
//   Name Reg   Size
//    - 
//   sb   b0   3
//   snb  b3   3
//   sbn  b6   2
//   sbnf b8   1
//   sn   c0   3
//   sbn  c3   3
//   sbnf c6   3
//   sbnf2c9   3
//   sbnf3c12  3
//   snb  c15  2

This is what I get (header.fx is the text file containing the shader) for
the shader in the test without disabling anything:
wine fxc.exe /E main /Tvs_3_0 header.fx
// Registers:
//
//   Name Reg   Size
//    - 
//   sb   b0   3
//   snb  b3   3
//   sbn  b6   3
//   sbnf b9   2
//   sn   i0   3
//   sbnf3i3   3
//   sbnf2i6   2
//   sbnf c0   3
//   sbnf2c3   3
//   sbnf3c6   3

I'm using this receipt to generate the binary blob:
wine fxc.exe /E main /Tvs_3_0 /Fo temporary.fxo header.fx 12
od -v -t x4 -A n -w32 temporary.fxo | sed 's/ /, 0x/g' | sed 's/^, //g' |
sed 's/\$/,/g'



Yeah, that matches my results.


It doesn't make a difference if you pass a valid or invalid shader to the
constant table interface. I think both should work fine. The question is,
why does the compiler produce code which may fail on your system? I guess
this will fail on any machine... are there systems where this code works? Or
is it the nature of the compiler to produce only sometimes code which works
when using optimization?



Well, probably the optimizations are just broken. On the other hand
the compiler would produce an error in these cases (but only on
Windows and also not a particularly helpful error message... oh well).
BTW, the shader generated by disabling the validation would fail at
CreateVertexShader() time on Windows (when it would be validated
again).

Ok, I think the optimization problem is another issue. It only produces 
a bad shader.






BTW, what needs to be fixed in Wine? I couldn't see anything obvious
by reading the test.


I got 104 test failures with this test case. Those are only in the part when
converting float - int - bool... Yeah, you couldn't see those from just
reading the code. ;-)

I've attached a new test with a shader binary without optimization. The
results are the same, only the register usage changed (and the shader size).

Cheers
Rico


I see. Not sure how much that actually matters, since setting the bool
field via the constant table wouldn't do the right thing anyway. I
guess it depends on the specific tests failing.


Matteo.

Lets see, I'll try to improve the test. At least we know now that it 
does some funky stuff. The failures are probably related to the structs 
are more then one time present.


Cheers
Rico
diff --git a/dlls/d3dx9_36/shader.c b/dlls/d3dx9_36/shader.c
index 8f18f5e..cce3e75 100644
--- a/dlls/d3dx9_36/shader.c
+++ b/dlls/d3dx9_36/shader.c
@@ -1888,6 +1888,13 @@ HRESULT WINAPI D3DXGetShaderConstantTableEx(const DWORD *byte_code, DWORD flags,
 for (i = 0; i  ctab_header-Constants; i++)
 {
 DWORD offset = constant_info[i].DefaultValue;
+UINT k;
+
+

Re: [PATCH 4/5] d3dx9/tests: Add ID3DXConstantTable struct test.

2013-08-02 Thread Matteo Bruni
2013/8/1 Matteo Bruni matteo.myst...@gmail.com:
 Instead of generating an entry for the struct with the correct
 members, the compiler generates TWO entries for sbnf, one with all its
 fields in D3DXRS_FLOAT4 and the other with D3DXRS_BOOL. Which, if I'm
 reading this correctly, makes 0 sense.
 Calling GetConstantByName() on the various fields then happen to
 return the first instance of the struct. It's the same with native
 d3dx9, FWIW.


I take this partially back, actually it might make sense after all.
Calling GetConstantDesc in general returns an array of
D3DXCONSTANT_DESC, not necessarily just one. I always wondered why but
I failed to make the connection to this case, until now.

Long wall of text follows, sorry. Case in point:

 // Registers:
 //
 //   Name Reg   Size
 //    - 
 //   sb   b0   3
 //   snb  b3   3
 //   sbn  b6   2
 //   sbnf b8   1
 //   sn   c0   3
 //   sbn  c3   3
 //   sbnf c6   3
 //   sbnf2c9   3
 //   sbnf3c12  3
 //   snb  c15  2


Notice how there is an overallocation of the constants: for sbnf there
are 3 float AND one bool registers allocated. Now, checking again
+d3dx output but tracing some more stuff:

trace:d3dx:parse_ctab_constant_type name sbnf, elements 1, defaultvalue 0x18e1d0
trace:d3dx:parse_ctab_constant_type regset D3DXRS_FLOAT4, regidx 6, regcount 3
trace:d3dx:parse_ctab_constant_type class D3DXPC_STRUCT, type
D3DXPT_VOID, rows 1, columns 3, elements 1, struct_members 3
trace:d3dx:parse_ctab_constant_type name b4, elements 1, defaultvalue 0x18e1d0
trace:d3dx:parse_ctab_constant_type regset D3DXRS_FLOAT4, regidx 6, regcount 0
trace:d3dx:parse_ctab_constant_type class D3DXPC_SCALAR, type
D3DXPT_BOOL, rows 1, columns 1, elements 1, struct_members 0
trace:d3dx:parse_ctab_constant_type name n4, elements 1, defaultvalue 0x18e1e0
trace:d3dx:parse_ctab_constant_type regset D3DXRS_FLOAT4, regidx 7, regcount 0
trace:d3dx:parse_ctab_constant_type class D3DXPC_SCALAR, type
D3DXPT_INT, rows 1, columns 1, elements 1, struct_members 0
trace:d3dx:parse_ctab_constant_type name f4, elements 1, defaultvalue 0x18e1f0
trace:d3dx:parse_ctab_constant_type regset D3DXRS_FLOAT4, regidx 8, regcount 0
trace:d3dx:parse_ctab_constant_type class D3DXPC_SCALAR, type
D3DXPT_FLOAT, rows 1, columns 1, elements 1, struct_members 0
trace:d3dx:parse_ctab_constant_type name sbnf, elements 1, defaultvalue 0x18e124
trace:d3dx:parse_ctab_constant_type regset D3DXRS_BOOL, regidx 8, regcount 1
trace:d3dx:parse_ctab_constant_type class D3DXPC_STRUCT, type
D3DXPT_VOID, rows 1, columns 3, elements 1, struct_members 3
trace:d3dx:parse_ctab_constant_type name b4, elements 1, defaultvalue 0x18e124
trace:d3dx:parse_ctab_constant_type regset D3DXRS_BOOL, regidx 8, regcount 0
trace:d3dx:parse_ctab_constant_type class D3DXPC_SCALAR, type
D3DXPT_BOOL, rows 1, columns 1, elements 1, struct_members 0
trace:d3dx:parse_ctab_constant_type name n4, elements 1, defaultvalue 0x18e128
trace:d3dx:parse_ctab_constant_type regset D3DXRS_BOOL, regidx 9, regcount 0
trace:d3dx:parse_ctab_constant_type class D3DXPC_SCALAR, type
D3DXPT_INT, rows 1, columns 1, elements 1, struct_members 0
trace:d3dx:parse_ctab_constant_type name f4, elements 1, defaultvalue 0x18e12c
trace:d3dx:parse_ctab_constant_type regset D3DXRS_BOOL, regidx 9, regcount 0
trace:d3dx:parse_ctab_constant_type class D3DXPC_SCALAR, type
D3DXPT_FLOAT, rows 1, columns 1, elements 1, struct_members 0

Sure enough, if you call GetConstantDesc() for sbnf, passing an array
of two D3DXCONSTANT_DESC and setting the count to 2, you get both
filled. Same with its struct members.
Here's what I get from a quickly hacked test with native d3dx9:

shader.c:6243: sbnf (0) registerset is 2.
shader.c:6244: sbnf (0) registerindex is 6.
shader.c:6245: sbnf (0) registercount is 3.
shader.c:6243: sbnf (1) registerset is 0.
shader.c:6244: sbnf (1) registerindex is 8.
shader.c:6245: sbnf (1) registercount is 1.

shader.c:6243: sbnf.b4 (0) registerset is 2.
shader.c:6244: sbnf.b4 (0) registerindex is 6.
shader.c:6245: sbnf.b4 (0) registercount is 1.
shader.c:6243: sbnf.b4 (1) registerset is 0.
shader.c:6244: sbnf.b4 (1) registerindex is 8.
shader.c:6245: sbnf.b4 (1) registercount is 1.

shader.c:6243: sbnf.n4 (0) registerset is 2.
shader.c:6244: sbnf.n4 (0) registerindex is 7.
shader.c:6245: sbnf.n4 (0) registercount is 1.
shader.c:6243: sbnf.n4 (1) registerset is 0.
shader.c:6244: sbnf.n4 (1) registerindex is 9.
shader.c:6245: sbnf.n4 (1) registercount is 0.

shader.c:6243: sbnf.f4 (0) registerset is 2.
shader.c:6244: sbnf.f4 (0) registerindex is 8.
shader.c:6245: sbnf.f4 (0) registercount is 1.
shader.c:6243: sbnf.f4 (1) registerset is 0.
shader.c:6244: sbnf.f4 (1) registerindex is 9.
shader.c:6245: sbnf.f4 (1) registercount is 0.

The 0 or 1 in parentheses indicate that the line refers to the first
or the second D3DXCONSTANT_DESC 

Re: [PATCH 4/5] d3dx9/tests: Add ID3DXConstantTable struct test.

2013-08-01 Thread Matteo Bruni
2013/8/1 Rico Schüller kgbric...@web.de:
 On 31.07.2013 00:14, Matteo Bruni wrote:

 2013/7/30 Rico Schüller kgbric...@web.de:

 Hi Matteo,

 please see the attached patch.


 On 25.07.2013 16:13, Matteo Bruni wrote:


 2013/7/24 Rico Schüller kgbric...@web.de:


 ---
dlls/d3dx9_36/tests/shader.c | 308
 +++
1 file changed, 308 insertions(+)


 This is okay, but as a followup can you add some tests with mixed-type
 structs? Something like:

 struct
 {
   float f;
   int i;
   bool b;
 };

 If you have already written tests of this kind, I'd like to know what
 does the compiler do in this case :)

 Single variables could only have the tested types (I was not able to
 generate other conversions than bool-bool, int-int, int-float,
 bool-float, float-float). But I found a way to do it with structs and
 there I found some issues. Hence this has to be fixed in wine, too.
 Thanks
 for the nice question. :-)

 Basically you got these for the struct:
 1. D3DXRS_FLOAT4: if one variable is used as float or a float variable is
 used or an int variable is used as bool (the compiler may do some
 optimization), else #2
 2. D3DXRS_BOOL: if a bool variable is used as bool (in an if clause),
 else
 #3
 3. D3DXRS_INT4

 It looks like you could only do it that way with unused variables. I'm
 not
 sure if this makes sense at all. Why would someone set an unused
 variable?
 Maybe I missed something? Do you know anything else?


 It does make some sense, although this is not what I expected. Also,
 I'm getting different results...

 If I understand correctly your test, all the fields of a structure
 share the same registerset. Which is silly, since AFAIU each member of
 the structure has a separate D3DXCONSTANT_DESC in the constant table,
 both on disk and in memory, there is no point the compiler should
 force the same registerset for all the struct members.

 Yes, they share all the same registerset. The optimization seems to force
 only the type of the register (it optimizes the not used members out).


 Under the constraint of forcing all the members in the same
 registerset, the conversion rules you mention make sense. In SM3 an
 if bool can be replaced by an if_comp with a float register and a
 rep/loop, which is controlled by an integer constant, can be emulated
 via loop unrolling (although I'm not sure how the compiler can
 possibly do that for the shader in your testcase). These are also
 pretty much the only use cases of bool and int constants and there are
 no int or bool non-constant registers so essentially no other type
 conversion is possible. You can check the plain text output from fxc
 to see how those constants are used in the shader code and how did the
 compiler manage to convert those constants from one type to another.

 I tried to compile your HLSL shader myself (I had to disable
 optimization though, otherwise compilation fails) and, assuming the
 text output of fxc matches what actually ends up in the shader
 bytecode, in general I'm getting different struct members in different
 registersets. E.g. snbf gets allocated to c6-c9 and b8. FWIW, I used
 fxc from the June 2010 DirectX SDK, on Windows 7.
 I'm not sure why my results are different from yours. Or am I
 misunderstanding the test?

 The bytecode should match the result in the text output. Also after some
 additional test these structs seem to set several registers (as could be
 seen in the text), so the constant table constant desc is not able to give a
 full description for these. So an app should not depend on those or did I
 miss something? It's getting tricky again.
 E.g.:
 struct {float f2; int n2; bool b2;} snb;
 sets:
 D3DXRS_FLOAT4 15,16 (60-68)
 D3DXRS_BOOL 3,4,5 (3-6)

 I'll send an update to the tests to cover these issue. I think I have to
 look at the binary and whats really in there. Hopefully that information
 could be found somewhere ...


The constant table could easily represent the situation by specifying
different register sets for different struct members.
But apparently the generated constant table is just broken. I ran the
test with WINEDEBUG=d3dx and this is an excerpt of the trace I got:

trace:d3dx:parse_ctab_constant_type name sbnf, elements 1, index 6,
defaultvalue 0x18e1d0, regset D3DXRS_FLOAT4
trace:d3dx:parse_ctab_constant_type class D3DXPC_STRUCT, type
D3DXPT_VOID, rows 1, columns 3, elements 1, struct_members 3
trace:d3dx:parse_ctab_constant_type name b4, elements 1, index 6,
defaultvalue 0x18e1d0, regset D3DXRS_FLOAT4
trace:d3dx:parse_ctab_constant_type class D3DXPC_SCALAR, type
D3DXPT_BOOL, rows 1, columns 1, elements 1, struct_members 0
trace:d3dx:parse_ctab_constant_type name n4, elements 1, index 7,
defaultvalue 0x18e1e0, regset D3DXRS_FLOAT4
trace:d3dx:parse_ctab_constant_type class D3DXPC_SCALAR, type
D3DXPT_INT, rows 1, columns 1, elements 1, struct_members 0
trace:d3dx:parse_ctab_constant_type name f4, elements 1, index 8,
defaultvalue 0x18e1f0, 

Re: [PATCH 4/5] d3dx9/tests: Add ID3DXConstantTable struct test.

2013-07-30 Thread Rico Schüller

Hi Matteo,

please see the attached patch.

On 25.07.2013 16:13, Matteo Bruni wrote:

2013/7/24 Rico Schüller kgbric...@web.de:

---
  dlls/d3dx9_36/tests/shader.c | 308
+++
  1 file changed, 308 insertions(+)



This is okay, but as a followup can you add some tests with mixed-type
structs? Something like:

struct
{
 float f;
 int i;
 bool b;
};

If you have already written tests of this kind, I'd like to know what
does the compiler do in this case :)

Single variables could only have the tested types (I was not able to 
generate other conversions than bool-bool, int-int, int-float, 
bool-float, float-float). But I found a way to do it with structs and 
there I found some issues. Hence this has to be fixed in wine, too. 
Thanks for the nice question. :-)


Basically you got these for the struct:
1. D3DXRS_FLOAT4: if one variable is used as float or a float variable 
is used or an int variable is used as bool (the compiler may do some 
optimization), else #2
2. D3DXRS_BOOL: if a bool variable is used as bool (in an if clause), 
else #3

3. D3DXRS_INT4

It looks like you could only do it that way with unused variables. I'm 
not sure if this makes sense at all. Why would someone set an unused 
variable? Maybe I missed something? Do you know anything else?


Cheers
Rico
diff --git a/dlls/d3dx9_36/tests/shader.c b/dlls/d3dx9_36/tests/shader.c
index 42c1455..be4b9cd 100644
--- a/dlls/d3dx9_36/tests/shader.c
+++ b/dlls/d3dx9_36/tests/shader.c
@@ -5585,6 +5585,436 @@ static const struct registerset_test registerset_test_bigvec_float[] =
 0x42800123, 0x43200123, 0x43600123}},
 };
 
+/*
+ * fxc.exe /Tvs_3_0
+ */
+#if 0
+struct {int n;  float f; bool b;} sb = {50, 7.6, 1};
+struct {bool b1; float f1; int n1;} sn = {1, 8.3, 51};
+struct {float f2; int n2; bool b2;} snb = {6.1, 53, 0};
+struct {float f3; bool b3; int n3;} sbn = {5.2, 1, 52};
+struct {bool b4; int n4; float f4;} sbnf = {1, 54, 4.3};
+struct {bool b5; int n5; float f5;} sbnf2 = {0, 55, 4.4};
+struct {float f6; bool b6; int n6;} sbnf3 = {8.7, 1, 56};
+float4 main(float4 pos : POSITION) : POSITION
+{
+float4 tmp = 0;
+int i;
+if (sb.b) for (i = 0; i  sn.n1; i++) tmp.x += pos.z;
+else if (snb.b2) for (i = 0; i  snb.n2; i++) tmp.y += pos.y;
+else if (sbn.b3) for (i = 0; i  sbn.n3; i++) tmp.y += pos.y;
+else if (sbnf.b4) for (i = 0; i  sbnf.n4; i++) tmp.y += pos.y * sbnf.f4;
+else if (sbnf2.f5) for (i = 0; i  sbnf2.n5; i++) tmp.y += pos.y;
+else if (sbnf3.n6)
+{
+tmp.y += pos.y;
+for (i = 0; i  sbnf3.n6; i++) tmp.x += pos.x;
+}
+return tmp;
+}
+#endif
+static const DWORD registerset_blob_mixed_struct[] =
+{
+0xfffe0300, 0x0103fffe, 0x42415443, 0x001c, 0x03d7, 0xfffe0300, 0x000a, 0x001c,
+0x0100, 0x03d0, 0x00e4, 0x, 0x0003, 0x013c, 0x014c, 0x0158,
+0x0006, 0x0003, 0x0180, 0x014c, 0x0190, 0x0002, 0x0003, 0x01b8,
+0x01c8, 0x0190, 0x0009, 0x0002, 0x01b8, 0x014c, 0x01f8, 0x00030002,
+0x0003, 0x0220, 0x0230, 0x01f8, 0x00060001, 0x0002, 0x0220, 0x0260,
+0x0290, 0x00060002, 0x0003, 0x02b8, 0x02c8, 0x0290, 0x00030001, 0x0003,
+0x02b8, 0x02f8, 0x0328, 0x0001, 0x0003, 0x034c, 0x035c, 0x038c,
+0x0003, 0x0003, 0x03b4, 0x03c4, 0x6e006273, 0xababab00, 0x0002, 0x00010001,
+0x0001, 0x, 0xabab0066, 0x0003, 0x00010001, 0x0001, 0x, 0xabab0062,
+0x0001, 0x00010001, 0x0001, 0x, 0x00e7, 0x00ec, 0x00fc, 0x0100,
+0x0110, 0x0114, 0x0005, 0x00030001, 0x00030001, 0x0124, 0x, 0x,
+0x, 0x006e6273, 0x62003366, 0x336e0033, 0xababab00, 0x015c, 0x0100, 0x015f,
+0x0114, 0x0162, 0x00ec, 0x0005, 0x00030001, 0x00030001, 0x0168, 0x666e6273,
+0x00346200, 0x6600346e, 0xabab0034, 0x0195, 0x0114, 0x0198, 0x00ec, 0x019b,
+0x0100, 0x0005, 0x00030001, 0x00030001, 0x01a0, 0x3f80, 0x, 0x,
+0x, 0x4258, 0x, 0x, 0x, 0x408a, 0x, 0x,
+0x, 0x666e6273, 0x35620032, 0x00356e00, 0xab003566, 0x01fe, 0x0114, 0x0201,
+0x00ec, 0x0204, 0x0100, 0x0005, 0x00030001, 0x00030001, 0x0208, 0x,
+0x, 0x, 0x, 0x425c, 0x, 0x, 0x, 0x408d,
+0x, 0x, 0x, 0x, 0x, 0x0001, 0x, 0x0037,
+0x, 0x0001, 0x, 0x0004, 0x, 0x0001, 0x, 0x666e6273,
+0x36660033, 0x00366200, 0xab00366e, 0x0296, 0x0100, 0x0299, 0x0114, 0x029c,
+0x00ec, 0x0005, 0x00030001, 0x00030001, 0x02a0, 0x410b, 0x, 0x,
+0x, 0x3f80, 0x, 

Re: [PATCH 4/5] d3dx9/tests: Add ID3DXConstantTable struct test.

2013-07-30 Thread Matteo Bruni
2013/7/30 Rico Schüller kgbric...@web.de:
 Hi Matteo,

 please see the attached patch.


 On 25.07.2013 16:13, Matteo Bruni wrote:

 2013/7/24 Rico Schüller kgbric...@web.de:

 ---
   dlls/d3dx9_36/tests/shader.c | 308
 +++
   1 file changed, 308 insertions(+)


 This is okay, but as a followup can you add some tests with mixed-type
 structs? Something like:

 struct
 {
  float f;
  int i;
  bool b;
 };

 If you have already written tests of this kind, I'd like to know what
 does the compiler do in this case :)

 Single variables could only have the tested types (I was not able to
 generate other conversions than bool-bool, int-int, int-float,
 bool-float, float-float). But I found a way to do it with structs and
 there I found some issues. Hence this has to be fixed in wine, too. Thanks
 for the nice question. :-)

 Basically you got these for the struct:
 1. D3DXRS_FLOAT4: if one variable is used as float or a float variable is
 used or an int variable is used as bool (the compiler may do some
 optimization), else #2
 2. D3DXRS_BOOL: if a bool variable is used as bool (in an if clause), else
 #3
 3. D3DXRS_INT4

 It looks like you could only do it that way with unused variables. I'm not
 sure if this makes sense at all. Why would someone set an unused variable?
 Maybe I missed something? Do you know anything else?


It does make some sense, although this is not what I expected. Also,
I'm getting different results...

If I understand correctly your test, all the fields of a structure
share the same registerset. Which is silly, since AFAIU each member of
the structure has a separate D3DXCONSTANT_DESC in the constant table,
both on disk and in memory, there is no point the compiler should
force the same registerset for all the struct members.

Under the constraint of forcing all the members in the same
registerset, the conversion rules you mention make sense. In SM3 an
if bool can be replaced by an if_comp with a float register and a
rep/loop, which is controlled by an integer constant, can be emulated
via loop unrolling (although I'm not sure how the compiler can
possibly do that for the shader in your testcase). These are also
pretty much the only use cases of bool and int constants and there are
no int or bool non-constant registers so essentially no other type
conversion is possible. You can check the plain text output from fxc
to see how those constants are used in the shader code and how did the
compiler manage to convert those constants from one type to another.

I tried to compile your HLSL shader myself (I had to disable
optimization though, otherwise compilation fails) and, assuming the
text output of fxc matches what actually ends up in the shader
bytecode, in general I'm getting different struct members in different
registersets. E.g. snbf gets allocated to c6-c9 and b8. FWIW, I used
fxc from the June 2010 DirectX SDK, on Windows 7.
I'm not sure why my results are different from yours. Or am I
misunderstanding the test?

BTW, what needs to be fixed in Wine? I couldn't see anything obvious
by reading the test.

Cheers,
Matteo.

 Cheers
 Rico




Re: [PATCH 4/5] d3dx9/tests: Add ID3DXConstantTable struct test.

2013-07-25 Thread Matteo Bruni
2013/7/24 Rico Schüller kgbric...@web.de:
 ---
  dlls/d3dx9_36/tests/shader.c | 308
 +++
  1 file changed, 308 insertions(+)


This is okay, but as a followup can you add some tests with mixed-type
structs? Something like:

struct
{
float f;
int i;
bool b;
};

If you have already written tests of this kind, I'd like to know what
does the compiler do in this case :)