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 // sbnf2 c9 3 // sbnf3 c12 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 // sbnf3 i3 3 // sbnf2 i6 2 // sbnf c0 3 // sbnf2 c3 3 // sbnf3 c6 3
I'm using this receipt to generate the binary blob: wine fxc.exe /E main /Tvs_3_0 /Fo temporary.fxo header.fx 1>2 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