This patch meant to be a minimal patch to prevent the infinitive loop. It's mostly for bug 39153 which is "implement enough D3D11 to run Tomb Raider 2013 without disabling d3d11 again" ;-) It allows the game to crash properly instead of looping indefinitely. It crashes because of some unsupported texture format with this patch. In order to make the patch small I haven't added WINED3DSIH_ entry for this opcode yet. Otherwise, I would have to reindent opcode tables also in shader.c, arb_program_shader.c and glsl_shader.c. The subject should actually be "wined3d: Correctly calculate length for SM4 dcl_immediateConstantBuffer opcode."
On Thu, Dec 3, 2015 at 4:48 PM, Henri Verbeet hverbeet@gmail.com wrote:
opcode_token = *(*ptr)++; opcode = opcode_token & WINED3D_SM4_OPCODE_MASK;
- len = ((opcode_token & WINED3D_SM4_INSTRUCTION_LENGTH_MASK) >> WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT) - 1;
- if (opcode == WINED3D_SM4_OP_DCL_IMMEDIATE_CONSTANT_BUFFER)
len = *(*ptr) - 1;
- else
len = ((opcode_token & WINED3D_SM4_INSTRUCTION_LENGTH_MASK) >> WINED3D_SM4_INSTRUCTION_LENGTH_SHIFT) - 1;
I don't think this is the right place to handle this. You should be able to handle this the same way as the other DCL_ opcodes. It should probably also have an entry in the opcode_info table. (Compare e.g. 6d948e1a8cdd8a9a5ae2b6124468275cbf13f2b8.)
I think I still need some additional code to handle this case before len is added to *ptr. WINED3D_SM4_INSTRUCTION_LENGTH is 0 for DCL_IMMEDIATE_CONSTANT_BUFFER opcodes. In the result we are adding 4294967295 to the pointer. I could use other type than DWORD so it would effectively decrement pointer pointer also on 64 bit but I doubt we want that. I could also check if len is 0 before decrementing it but it is not right for other opcodes than DCL_IMMEDIATE_CONSTANT_BUFFER.