diff --git a/patches/d3dx9_36-D3DXDisassembleShader/0004-d3dx9_36-Implement-D3DXDisassembleShader.patch b/patches/d3dx9_36-D3DXDisassembleShader/0004-d3dx9_36-Implement-D3DXDisassembleShader.patch index 794c2113..75dc8a54 100644 --- a/patches/d3dx9_36-D3DXDisassembleShader/0004-d3dx9_36-Implement-D3DXDisassembleShader.patch +++ b/patches/d3dx9_36-D3DXDisassembleShader/0004-d3dx9_36-Implement-D3DXDisassembleShader.patch @@ -1,16 +1,27 @@ -From 0e8c5ad0e1d2c798a28f14677ca0f8a51c26f2be Mon Sep 17 00:00:00 2001 +From e978148d40107aa9ec6d1affc65f4386188940eb Mon Sep 17 00:00:00 2001 From: Christian Costa Date: Sat, 13 Feb 2016 15:29:37 +0100 -Subject: d3dx9_36: Implement D3DXDisassembleShader. +Subject: d3dx9_36: Implement D3DXDisassembleShader. (v2) +Changes in v2 (by Christian Costa): + * More generic code for D3DXDisassembleShader. --- - dlls/d3dx9_36/shader.c | 297 ++++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 295 insertions(+), 2 deletions(-) + dlls/d3dx9_36/shader.c | 331 ++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 328 insertions(+), 3 deletions(-) diff --git a/dlls/d3dx9_36/shader.c b/dlls/d3dx9_36/shader.c -index 50d5669..0879557 100644 +index 50d5669..d2ee03f 100644 --- a/dlls/d3dx9_36/shader.c +++ b/dlls/d3dx9_36/shader.c +@@ -1,7 +1,7 @@ + /* + * Copyright 2008 Luis Busquets + * Copyright 2009 Matteo Bruni +- * Copyright 2010, 2013 Christian Costa ++ * Copyright 2010, 2013, 2016 Christian Costa + * Copyright 2011 Travis Athougies + * + * This library is free software; you can redistribute it and/or @@ -21,6 +21,7 @@ #include "config.h" @@ -19,100 +30,10 @@ index 50d5669..0879557 100644 #include "wine/debug.h" #include "wine/unicode.h" -@@ -2147,10 +2148,302 @@ HRESULT WINAPI D3DXGetShaderSamplers(const DWORD *byte_code, const char **sample +@@ -2147,10 +2148,334 @@ HRESULT WINAPI D3DXGetShaderSamplers(const DWORD *byte_code, const char **sample return D3D_OK; } -+static const struct -+{ -+ const char *name; -+ int length; -+} -+opcode[] = -+{ -+ { "nop", 0 }, /* D3DSIO_NOP */ -+ { "mov", 2 }, /* D3DSIO_MOV */ -+ { "add", 3 }, /* D3DSIO_ADD */ -+ { "sub", 3 }, /* D3DSIO_SUB */ -+ { "mad", 4 }, /* D3DSIO_MAD */ -+ { "mul", 3 }, /* D3DSIO_MUL */ -+ { "rcp", 2 }, /* D3DSIO_RCP */ -+ { "rsq", 2 }, /* D3DSIO_RSQ */ -+ { "dp3", 3 }, /* D3DSIO_DP3 */ -+ { "dp4", 3 }, /* D3DSIO_DP4 */ -+ { "min", 3 }, /* D3DSIO_MIN */ -+ { "max", 3 }, /* D3DSIO_MAX */ -+ { "slt", 3 }, /* D3DSIO_SLT */ -+ { "sge", 3 }, /* D3DSIO_SGE */ -+ { "exp", 2 }, /* D3DSIO_EXP */ -+ { "log", 2 }, /* D3DSIO_LOG */ -+ { "lit", 2 }, /* D3DSIO_LIT */ -+ { "dst", 3 }, /* D3DSIO_DST */ -+ { "lrp", 4 }, /* D3DSIO_LRP */ -+ { "frc", 2 }, /* D3DSIO_FRC */ -+ { "m4x4", 3 }, /* D3DSIO_M4x4 */ -+ { "m4x3", 3 }, /* D3DSIO_M4x3 */ -+ { "m3x4", 3 }, /* D3DSIO_M3x4 */ -+ { "m3x3", 3 }, /* D3DSIO_M3x3 */ -+ { "m3x2", 3 }, /* D3DSIO_M3x2 */ -+ { "call", 1 }, /* D3DSIO_CALL */ -+ { "callnz", 2 }, /* D3DSIO_CALLNZ */ -+ { "loop", 2 }, /* D3DSIO_LOOP */ -+ { "ret", 0 }, /* D3DSIO_RET */ -+ { "endloop", 1 }, /* D3DSIO_ENDLOOP */ -+ { "label", 1 }, /* D3DSIO_LABEL */ -+ { "dcl", 1 }, /* D3DSIO_DCL (handled separately) */ -+ { "pow", 3 }, /* D3DSIO_POW */ -+ { "crs", 3 }, /* D3DSIO_CRS */ -+ { "sgn", 4 }, /* D3DSIO_SGN */ -+ { "abs", 2 }, /* D3DSIO_ABS */ -+ { "nrm", 2 }, /* D3DSIO_NRM */ -+ { "sincos", 4 }, /* D3DSIO_SINCOS */ -+ { "rep", 1 }, /* D3DSIO_REP */ -+ { "endrep", 0 }, /* D3DSIO_ENDREP */ -+ { "if", 1 }, /* D3DSIO_IF */ -+ { "if", 2 }, /* D3DSIO_IFC */ -+ { "else", 0 }, /* D3DSIO_ELSE */ -+ { "endif", 0 }, /* D3DSIO_ENDIF */ -+ { "break", 0 }, /* D3DSIO_BREAK */ -+ { "break", 2 }, /* D3DSIO_BREAKC */ -+ { "mova", 2 }, /* D3DSIO_MOVA */ -+ { "defb", 2 }, /* D3DSIO_DEFB */ -+ { "defi", 2 }, /* D3DSIO_DEFI */ -+ { "texcoord", 1 }, /* D3DSIO_TEXCOORD */ -+ { "texkill", 1 }, /* D3DSIO_TEXKILL */ -+ { "texld", 3 }, /* D3DSIO_TEX */ -+ { "texbem", 2 }, /* D3DSIO_TEXBEM */ -+ { "texbeml", 2 }, /* D3DSIO_TEXBEML */ -+ { "texreg2ar", 2 }, /* D3DSIO_TEXREG2AR */ -+ { "texreg2gb", 2 }, /* D3DSIO_TEXREG2GB */ -+ { "texm3x2pad", 2 }, /* D3DSIO_TEXM3x2PAD */ -+ { "texm3x2tex", 2 }, /* D3DSIO_TEXM3x2TEX */ -+ { "texm3x3pad", 2 }, /* D3DSIO_TEXM3x3PAD */ -+ { "texm3x3tex", 2 }, /* D3DSIO_TEXM3x3TEX */ -+ { "texm3x3diff", 2 }, /* D3DSIO_TEXM3x3DIFF */ -+ { "texm3x3spec", 3 }, /* D3DSIO_TEXM3x3SPEC */ -+ { "texm3x3vspec", 2 }, /* D3DSIO_TEXM3x3VSPEC */ -+ { "expp", 2 }, /* D3DSIO_EXPP */ -+ { "logp", 2 }, /* D3DSIO_LOGP */ -+ { "cnd", 4 }, /* D3DSIO_CND */ -+ { "def", 5 }, /* D3DSIO_DEF (handled separately) */ -+ { "texreg2rgb", 2 }, /* D3DSIO_TEXREG2RGB */ -+ { "texdp3tex", 2 }, /* D3DSIO_TEXDP3TEX */ -+ { "texm3x2depth", 2 }, /* D3DSIO_TEXM3x2DEPTH */ -+ { "texdp3", 2 }, /* D3DSIO_TEXDP3 */ -+ { "texm3x3", 2 }, /* D3DSIO_TEXM3x3 */ -+ { "texdepth", 1 }, /* D3DSIO_TEXDEPTH */ -+ { "cmp", 4 }, /* D3DSIO_CMP */ -+ { "bem", 3 }, /* D3DSIO_BEM */ -+ { "dp2add", 4 }, /* D3DSIO_DP2ADD */ -+ { "dsx", 2 }, /* D3DSIO_DSX */ -+ { "dsy", 2 }, /* D3DSIO_DSY */ -+ { "texldd", 5 }, /* D3DSIO_TEXLDD */ -+ { "setp", 3 }, /* D3DSIO_SETP */ -+ { "texldl", 3 }, /* D3DSIO_TEXLDL */ -+ { "breakp", 1 } /* D3DSIO_BREAKP */ -+}; + +static const char *decl_usage[] = { "position", "blendweight", "blendindices", "normal", "psize", "texcoord", + "tangent", "binormal", "tessfactor", "positiont", "color" }; @@ -191,6 +112,192 @@ index 50d5669..0879557 100644 + + return buf - buffer; +} ++ ++struct instr_info ++{ ++ DWORD opcode; ++ const char *name; ++ int length; ++ int (*function)(const struct instr_info *info, DWORD **ptr, char *buffer, BOOL ps); ++ WORD min_version; ++ WORD max_version; ++}; ++ ++static int instr_comment(const struct instr_info *info, DWORD **ptr, char *buffer, BOOL ps) ++{ ++ *ptr += 1 + ((**ptr & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT); ++ return 0; ++} ++ ++static int instr_def(const struct instr_info *info, DWORD **ptr, char *buffer, BOOL ps) ++{ ++ int len = sprintf(buffer, " def c%d, %g, %g, %g, %g\n", *(*ptr+1) & D3DSP_REGNUM_MASK, ++ (double)*(float*)(*ptr+2), (double)*(float*)(*ptr+3), ++ (double)*(float*)(*ptr+4), (double)*(float*)(*ptr+5)); ++ *ptr += 6; ++ return len; ++} ++ ++static int instr_dcl(const struct instr_info *info, DWORD **ptr, char *buffer, BOOL ps) ++{ ++ DWORD param1 = *++*ptr; ++ DWORD param2 = *++*ptr; ++ DWORD usage = (param1 & D3DSP_DCL_USAGE_MASK) >> D3DSP_DCL_USAGE_SHIFT; ++ DWORD usage_index = (param1 & D3DSP_DCL_USAGEINDEX_MASK) >> D3DSP_DCL_USAGEINDEX_SHIFT; ++ char *buf = buffer; ++ ++ buf += sprintf(buf, " dcl"); ++ if (ps) ++ { ++ if (param1 & D3DSP_TEXTURETYPE_MASK) ++ buf += sprintf(buf, "_%s", (usage <= D3DSTT_VOLUME) ? ++ tex_type[(param1 & D3DSP_TEXTURETYPE_MASK) >> D3DSP_TEXTURETYPE_SHIFT] : "???"); ++ } ++ else ++ { ++ buf += sprintf(buf, "_%s", (usage <= D3DDECLUSAGE_COLOR) ? decl_usage[usage] : "???"); ++ if (usage_index) ++ buf += sprintf(buf, "%d", usage_index); ++ } ++ ++ buf += add_modifier(buf, param2); ++ buf += sprintf(buf, " "); ++ buf += add_register(buf, param2, TRUE, TRUE); ++ buf += sprintf(buf, "\n"); ++ (*ptr)++; ++ return buf - buffer; ++} ++ ++static int instr_generic(const struct instr_info *info, DWORD **ptr, char *buffer, BOOL ps) ++{ ++ char *buf = buffer; ++ int j; ++ ++ buf += sprintf(buf, " %s", info->name); ++ (*ptr)++; ++ ++ if (info->length) ++ { ++ buf += add_modifier(buf, **ptr); ++ ++ for (j = 0; j < info->length; j++) ++ { ++ buf += sprintf(buf, "%s ", j ? "," : ""); ++ ++ if ((j != 0) && ((**ptr & D3DSP_SRCMOD_MASK) != D3DSPSM_NONE)) ++ { ++ if ((**ptr & D3DSP_SRCMOD_MASK) == D3DSPSM_NEG) ++ buf += sprintf(buf, "-"); ++ else ++ buf += sprintf(buf, "*"); ++ } ++ ++ buf += add_register(buf, **ptr, j == 0, ps); ++ ++ if (*(*ptr)++ & D3DVS_ADDRESSMODE_MASK) ++ { ++ buf += sprintf(buf, "["); ++ buf += add_register(buf, **ptr, FALSE, FALSE); ++ buf += sprintf(buf, "]"); ++ (*ptr)++; ++ } ++ } ++ } ++ buf += sprintf(buf, "\n"); ++ return buf - buffer; ++} ++ ++const struct instr_info instructions[] = ++{ ++ { D3DSIO_NOP, "nop", 0, instr_generic, 0x0100, 0xFFFF }, ++ { D3DSIO_MOV, "mov", 2, instr_generic, 0x0100, 0xFFFF }, ++ { D3DSIO_ADD, "add", 3, instr_generic, 0x0100, 0xFFFF }, ++ { D3DSIO_SUB, "sub", 3, instr_generic, 0x0100, 0xFFFF }, ++ { D3DSIO_MAD, "mad", 4, instr_generic, 0x0100, 0xFFFF }, ++ { D3DSIO_MUL, "mul", 3, instr_generic, 0x0100, 0xFFFF }, ++ { D3DSIO_RCP, "rcp", 2, instr_generic, 0x0100, 0xFFFF }, /* >= 2.0 for PS */ ++ { D3DSIO_RSQ, "rsq", 2, instr_generic, 0x0100, 0xFFFF }, /* >= 2.0 for PS */ ++ { D3DSIO_DP3, "dp3", 3, instr_generic, 0x0100, 0xFFFF }, ++ { D3DSIO_DP4, "dp4", 3, instr_generic, 0x0100, 0xFFFF }, /* >= 1.2 for PS */ ++ { D3DSIO_MIN, "min", 3, instr_generic, 0x0100, 0xFFFF }, /* >= 2.0 for PS */ ++ { D3DSIO_MAX, "max", 3, instr_generic, 0x0100, 0xFFFF }, /* >= 2.0 for PS */ ++ { D3DSIO_SLT, "slt", 3, instr_generic, 0x0100, 0xFFFF }, ++ { D3DSIO_SGE, "sge", 3, instr_generic, 0x0100, 0xFFFF }, /* VS only */ ++ { D3DSIO_EXP, "exp", 2, instr_generic, 0x0100, 0xFFFF }, /* >= 2.0 for PS */ ++ { D3DSIO_LOG, "log", 2, instr_generic, 0x0100, 0xFFFF }, /* >= 2.0 for PS */ ++ { D3DSIO_LIT, "lit", 2, instr_generic, 0x0100, 0xFFFF }, /* VS only */ ++ { D3DSIO_DST, "dst", 3, instr_generic, 0x0100, 0xFFFF }, /* VS only */ ++ { D3DSIO_LRP, "lrp", 4, instr_generic, 0x0100, 0xFFFF }, /* >= 2.0 for VS */ ++ { D3DSIO_FRC, "frc", 2, instr_generic, 0x0100, 0xFFFF }, /* >= 2.0 for PS */ ++ { D3DSIO_M4x4, "m4x4", 3, instr_generic, 0x0100, 0xFFFF }, /* >= 2.0 for PS */ ++ { D3DSIO_M4x3, "m4x3", 3, instr_generic, 0x0100, 0xFFFF }, /* >= 2.0 for PS */ ++ { D3DSIO_M3x4, "m3x4", 3, instr_generic, 0x0100, 0xFFFF }, /* >= 2.0 for PS */ ++ { D3DSIO_M3x3, "m3x3", 3, instr_generic, 0x0100, 0xFFFF }, /* >= 2.0 for PS */ ++ { D3DSIO_M3x2, "m3x2", 3, instr_generic, 0x0100, 0xFFFF }, /* >= 2.0 for PS */ ++ { D3DSIO_CALL, "call", 1, instr_generic, 0x0200, 0xFFFF }, /* >= 2.a for PS */ ++ { D3DSIO_CALLNZ, "callnz", 2, instr_generic, 0x0200, 0xFFFF }, /* >= 2.a for PS */ ++ { D3DSIO_LOOP, "loop", 2, instr_generic, 0x0200, 0xFFFF }, /* >= 3.0 for PS */ ++ { D3DSIO_RET, "ret", 0, instr_generic, 0x0200, 0xFFFF }, /* >= 2.a for PS */ ++ { D3DSIO_ENDLOOP, "endloop", 1, instr_generic, 0x0200, 0xFFFF }, /* >= 3.0 for PS */ ++ { D3DSIO_LABEL, "label", 1, instr_generic, 0x0200, 0xFFFF }, /* >= 2.a for PS */ ++ { D3DSIO_DCL, "dcl", 1, instr_dcl, 0x0100, 0xFFFF }, ++ { D3DSIO_POW, "pow", 3, instr_generic, 0x0200, 0xFFFF }, ++ { D3DSIO_CRS, "crs", 3, instr_generic, 0x0200, 0xFFFF }, ++ { D3DSIO_SGN, "sgn", 4, instr_generic, 0x0200, 0xFFFF }, /* VS only */ ++ { D3DSIO_ABS, "abs", 2, instr_generic, 0x0200, 0xFFFF }, ++ { D3DSIO_NRM, "nrm", 2, instr_generic, 0x0200, 0xFFFF }, ++ { D3DSIO_SINCOS, "sincos", 4, instr_generic, 0x0200, 0x02FF }, ++ { D3DSIO_SINCOS, "sincos", 2, instr_generic, 0x0300, 0xFFFF }, ++ { D3DSIO_REP, "rep", 1, instr_generic, 0x0200, 0xFFFF }, /* >= 2.a for PS */ ++ { D3DSIO_ENDREP, "endrep", 0, instr_generic, 0x0200, 0xFFFF }, /* >= 2.a for PS */ ++ { D3DSIO_IF, "if", 1, instr_generic, 0x0200, 0xFFFF }, /* >= 2.a for PS */ ++ { D3DSIO_IFC, "if_comp", 2, instr_generic, 0x0200, 0xFFFF }, ++ { D3DSIO_ELSE, "else", 0, instr_generic, 0x0200, 0xFFFF }, /* >= 2.a for PS */ ++ { D3DSIO_ENDIF, "endif", 0, instr_generic, 0x0200, 0xFFFF }, /* >= 2.a for PS */ ++ { D3DSIO_BREAK, "break", 0, instr_generic, 0x0201, 0xFFFF }, ++ { D3DSIO_BREAKC, "break_comp", 2, instr_generic, 0x0201, 0xFFFF }, ++ { D3DSIO_MOVA, "mova", 2, instr_generic, 0x0200, 0xFFFF }, /* VS only */ ++ { D3DSIO_DEFB, "defb", 2, instr_generic, 0x0100, 0xFFFF }, ++ { D3DSIO_DEFI, "defi", 2, instr_generic, 0x0100, 0xFFFF }, ++ { D3DSIO_TEXCOORD, "texcoord", 1, instr_generic, 0x0100, 0x0103 }, /* PS only */ ++ { D3DSIO_TEXCOORD, "texcrd", 2, instr_generic, 0x0104, 0x0104 }, /* PS only */ ++ { D3DSIO_TEXKILL, "texkill", 1, instr_generic, 0x0100, 0xFFFF }, /* PS only */ ++ { D3DSIO_TEX, "tex", 1, instr_generic, 0x0100, 0x0103 }, /* PS only */ ++ { D3DSIO_TEX, "texld", 2, instr_generic, 0x0104, 0x0104 }, /* PS only */ ++ { D3DSIO_TEX, "texld", 3, instr_generic, 0x0200, 0xFFFF }, /* PS only */ ++ { D3DSIO_TEXBEM, "texbem", 2, instr_generic, 0x0100, 0x0103 }, /* PS only */ ++ { D3DSIO_TEXBEML, "texbeml", 2, instr_generic, 0x0100, 0x0103 }, /* PS only */ ++ { D3DSIO_TEXREG2AR, "texreg2ar", 2, instr_generic, 0x0100, 0x0103 }, /* PS only */ ++ { D3DSIO_TEXREG2GB, "texreg2gb", 2, instr_generic, 0x0102, 0x0103 }, /* PS only */ ++ { D3DSIO_TEXM3x2PAD, "texm3x2pad", 2, instr_generic, 0x0100, 0x0103 }, /* PS only */ ++ { D3DSIO_TEXM3x2TEX, "texm3x2tex", 2, instr_generic, 0x0100, 0x0103 }, /* PS only */ ++ { D3DSIO_TEXM3x3PAD, "texm3x3pad", 2, instr_generic, 0x0100, 0x0103 }, /* PS only */ ++ { D3DSIO_TEXM3x3TEX, "texm3x3tex", 2, instr_generic, 0x0100, 0x0103 }, /* PS only */ ++ { D3DSIO_TEXM3x3DIFF, "texm3x3diff", 2, instr_generic, 0x0100, 0xFFFF }, /* PS only - Not documented */ ++ { D3DSIO_TEXM3x3SPEC, "texm3x3spec", 3, instr_generic, 0x0100, 0x0103 }, /* PS only */ ++ { D3DSIO_TEXM3x3VSPEC, "texm3x3vspec", 2, instr_generic, 0x0100, 0x0103 }, /* PS only */ ++ { D3DSIO_EXPP, "expp", 2, instr_generic, 0x0100, 0xFFFF }, /* VS only */ ++ { D3DSIO_LOGP, "logp", 2, instr_generic, 0x0100, 0xFFFF }, /* VS only */ ++ { D3DSIO_CND, "cnd", 4, instr_generic, 0x0100, 0x0104 }, /* PS only */ ++ { D3DSIO_DEF, "def", 5, instr_def, 0x0100, 0xFFFF }, ++ { D3DSIO_TEXREG2RGB, "texreg2rgb", 2, instr_generic, 0x0102, 0x0103 }, /* PS only */ ++ { D3DSIO_TEXDP3TEX, "texdp3tex", 2, instr_generic, 0x0102, 0x0103 }, /* PS only */ ++ { D3DSIO_TEXM3x2DEPTH, "texm3x2depth", 2, instr_generic, 0x0103, 0x0103 }, /* PS only */ ++ { D3DSIO_TEXDP3, "texdp3", 2, instr_generic, 0x0102, 0x0103 }, /* PS only */ ++ { D3DSIO_TEXM3x3, "texm3x3", 2, instr_generic, 0x0102, 0x0103 }, /* PS only */ ++ { D3DSIO_TEXDEPTH, "texdepth", 1, instr_generic, 0x0104, 0x0104 }, /* PS only */ ++ { D3DSIO_CMP, "cmp", 4, instr_generic, 0x0102, 0xFFFF }, /* PS only */ ++ { D3DSIO_BEM, "bem", 3, instr_generic, 0x0104, 0x0104 }, /* PS only */ ++ { D3DSIO_DP2ADD, "dp2add", 4, instr_generic, 0x0200, 0xFFFF }, /* PS only */ ++ { D3DSIO_DSX, "dsx", 2, instr_generic, 0x0201, 0xFFFF }, /* PS only */ ++ { D3DSIO_DSY, "dsy", 2, instr_generic, 0x0201, 0xFFFF }, /* PS only */ ++ { D3DSIO_TEXLDD, "texldd", 5, instr_generic, 0x0201, 0xFFFF }, /* PS only - not existing for 2.b */ ++ { D3DSIO_SETP, "setp_comp", 3, instr_generic, 0x0201, 0xFFFF }, ++ { D3DSIO_TEXLDL, "texldl", 3, instr_generic, 0x0300, 0xFFFF }, ++ { D3DSIO_BREAKP, "breakp", 1, instr_generic, 0x0201, 0xFFFF }, ++ { D3DSIO_PHASE, "phase", 0, instr_generic, 0x0104, 0x0104 }, /* PS only */ ++ { D3DSIO_COMMENT, "", 0, instr_comment, 0x0100, 0xFFFF } ++}; + HRESULT WINAPI D3DXDisassembleShader(const DWORD *shader, BOOL colorcode, const char *comments, ID3DXBuffer **disassembly) { @@ -200,23 +307,27 @@ index 50d5669..0879557 100644 + char *buffer, *buf; + UINT capacity = 4096; + BOOL ps; ++ WORD version; + HRESULT hr; + + TRACE("%p %d %s %p\n", shader, colorcode, debugstr_a(comments), disassembly); + + if (!shader || !disassembly) -+ return E_POINTER; ++ return D3DERR_INVALIDCALL; + + buf = buffer = HeapAlloc(GetProcessHeap(), 0, capacity); + if (!buffer) + return E_OUTOFMEMORY; + + ps = (*ptr >> 16) & 1; ++ version = *ptr & 0xFFFF; + buf += sprintf(buf, " %s_%d_%d\n", ps ? "ps" : "vs", D3DSHADER_VERSION_MAJOR(*ptr), D3DSHADER_VERSION_MINOR(*ptr)); + ptr++; + + while (*ptr != D3DSIO_END) + { ++ DWORD index; ++ + if ((buf - buffer + 128) > capacity) + { + UINT count = buf - buffer; @@ -231,87 +342,19 @@ index 50d5669..0879557 100644 + buf = buffer + count; + } + -+ if ((*ptr & D3DSI_OPCODE_MASK) == D3DSIO_COMMENT) ++ for (index = 0; index < sizeof(instructions)/sizeof(instructions[0]); index++) ++ if (((*ptr & D3DSI_OPCODE_MASK) == instructions[index].opcode) && ++ (version >= instructions[index].min_version) && (version <= instructions[index].max_version)) ++ break; ++ ++ if (index != sizeof(instructions)/sizeof(instructions[0])) + { -+ ptr += 1 + ((*ptr & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT); -+ } -+ else if ((*ptr & D3DSI_OPCODE_MASK) == D3DSIO_DEF) -+ { -+ buf += sprintf(buf, " def c%d, %g, %g, %g, %g\n", *(ptr+1) & D3DSP_REGNUM_MASK, -+ (double)*(float*)(ptr+2), (double)*(float*)(ptr+3), -+ (double)*(float*)(ptr+4), (double)*(float*)(ptr+5)); -+ ptr += 6; -+ } -+ else if ((*ptr & D3DSI_OPCODE_MASK) == D3DSIO_DCL) -+ { -+ DWORD param1 = *++ptr; -+ DWORD param2 = *++ptr; -+ DWORD usage = (param1 & D3DSP_DCL_USAGE_MASK) >> D3DSP_DCL_USAGE_SHIFT; -+ DWORD usage_index = (param1 & D3DSP_DCL_USAGEINDEX_MASK) >> D3DSP_DCL_USAGEINDEX_SHIFT; -+ -+ buf += sprintf(buf, " dcl"); -+ if (ps) -+ { -+ if (param1 & D3DSP_TEXTURETYPE_MASK) -+ buf += sprintf(buf, "_%s", (usage <= D3DSTT_VOLUME) ? -+ tex_type[(param1 & D3DSP_TEXTURETYPE_MASK) >> D3DSP_TEXTURETYPE_SHIFT] : "???"); -+ } -+ else -+ { -+ buf += sprintf(buf, "_%s", (usage <= D3DDECLUSAGE_COLOR) ? decl_usage[usage] : "???"); -+ if (usage_index) -+ buf += sprintf(buf, "%d", usage_index); -+ } -+ -+ buf += add_modifier(buf, param2); -+ buf += sprintf(buf, " "); -+ buf += add_register(buf, param2, TRUE, TRUE); -+ buf += sprintf(buf, "\n"); -+ ptr++; -+ } -+ else if ((*ptr & D3DSI_OPCODE_MASK) <= D3DSIO_BREAKP) -+ { -+ DWORD index = *ptr & D3DSI_OPCODE_MASK; -+ int j; -+ -+ if (index >= 64) -+ index -= 15; -+ buf += sprintf(buf, " %s", opcode[index].name); -+ ptr++; -+ -+ if (opcode[index].length) -+ { -+ buf += add_modifier(buf, *ptr); -+ -+ for (j = 0; j < opcode[index].length; j++) -+ { -+ buf += sprintf(buf, "%s ", j ? "," : ""); -+ -+ if ((j != 0) && ((*ptr & D3DSP_SRCMOD_MASK) != D3DSPSM_NONE)) -+ { -+ if ((*ptr & D3DSP_SRCMOD_MASK) == D3DSPSM_NEG) -+ buf += sprintf(buf, "-"); -+ else -+ buf += sprintf(buf, "*"); -+ } -+ -+ buf += add_register(buf, *ptr, j == 0, ps); -+ -+ if (*ptr++ & D3DVS_ADDRESSMODE_MASK) -+ { -+ buf += sprintf(buf, "["); -+ buf += add_register(buf, *ptr, FALSE, FALSE); -+ buf += sprintf(buf, "]"); -+ ptr++; -+ } -+ } -+ } -+ buf += sprintf(buf, "\n"); ++ buf += instructions[index].function(&(instructions[index]), &ptr, buf, ps); + } + else + { -+ buf += sprintf(buf, " ???\n"); -+ ptr++; ++ buf += sprintf(buf, " ??? (Unknown opcode %x)\n", *ptr); ++ while (*++ptr & (1u << 31)); + } + } + diff --git a/patches/d3dx9_36-D3DXDisassembleShader/0005-d3dx9_36-tests-Add-initial-tests-for-D3DXDisassemble.patch b/patches/d3dx9_36-D3DXDisassembleShader/0005-d3dx9_36-tests-Add-initial-tests-for-D3DXDisassemble.patch index 3fb09aff..0a622a85 100644 --- a/patches/d3dx9_36-D3DXDisassembleShader/0005-d3dx9_36-tests-Add-initial-tests-for-D3DXDisassemble.patch +++ b/patches/d3dx9_36-D3DXDisassembleShader/0005-d3dx9_36-tests-Add-initial-tests-for-D3DXDisassemble.patch @@ -1,28 +1,14 @@ -From 9ebdb276a341f55b764eb6d0ac4e6600da9a792d Mon Sep 17 00:00:00 2001 +From 9dec4fdb1b9f89a5709603247fc8c6bf52eff764 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Mon, 15 Feb 2016 08:25:58 +0100 Subject: d3dx9_36/tests: Add initial tests for D3DXDisassembleShader. --- - dlls/d3dx9_36/shader.c | 2 +- dlls/d3dx9_36/tests/shader.c | 46 ++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 47 insertions(+), 1 deletion(-) + 1 file changed, 46 insertions(+) -diff --git a/dlls/d3dx9_36/shader.c b/dlls/d3dx9_36/shader.c -index c364d45..8fb63aa 100644 ---- a/dlls/d3dx9_36/shader.c -+++ b/dlls/d3dx9_36/shader.c -@@ -2363,7 +2363,7 @@ HRESULT WINAPI D3DXDisassembleShader(const DWORD *shader, BOOL colorcode, const - TRACE("%p %d %s %p\n", shader, colorcode, debugstr_a(comments), disassembly); - - if (!shader || !disassembly) -- return E_POINTER; -+ return D3DERR_INVALIDCALL; - - buf = buffer = HeapAlloc(GetProcessHeap(), 0, capacity); - if (!buffer) diff --git a/dlls/d3dx9_36/tests/shader.c b/dlls/d3dx9_36/tests/shader.c -index 946143e..a5f194d 100644 +index 946143e..b12bf5b 100644 --- a/dlls/d3dx9_36/tests/shader.c +++ b/dlls/d3dx9_36/tests/shader.c @@ -6628,6 +6628,51 @@ if (0) @@ -69,8 +55,8 @@ index 946143e..a5f194d 100644 + ret = D3DXDisassembleShader(simple_ps, FALSE, NULL, &disassembly); + ok(ret == D3D_OK, "Failed with %#x\n", ret); + ptr = ID3DXBuffer_GetBufferPointer(disassembly); -+ todo_wine ok(!memcmp(ptr, disasm_ps, sizeof(disasm_ps) - 1), /* compare beginning */ -+ "Returned '%s', expected '%s'\n", ptr, disasm_ps); ++ ok(!memcmp(ptr, disasm_ps, sizeof(disasm_ps) - 1), /* compare beginning */ ++ "Returned '%s', expected '%s'\n", ptr, disasm_ps); + ID3DXBuffer_Release(disassembly); +} + diff --git a/patches/d3dx9_36-D3DXDisassembleShader/0006-d3dx9_36-tests-Add-additional-tests-for-special-case.patch b/patches/d3dx9_36-D3DXDisassembleShader/0006-d3dx9_36-tests-Add-additional-tests-for-special-case.patch new file mode 100644 index 00000000..df97c292 --- /dev/null +++ b/patches/d3dx9_36-D3DXDisassembleShader/0006-d3dx9_36-tests-Add-additional-tests-for-special-case.patch @@ -0,0 +1,200 @@ +From 01824b066e4d25ae049d924657d9c074bcb81344 Mon Sep 17 00:00:00 2001 +From: Christian Costa +Date: Tue, 16 Feb 2016 12:11:45 +0100 +Subject: d3dx9_36/tests: Add additional tests for special cases. + +--- + dlls/d3dx9_36/tests/shader.c | 163 +++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 163 insertions(+) + +diff --git a/dlls/d3dx9_36/tests/shader.c b/dlls/d3dx9_36/tests/shader.c +index b12bf5b..6bb6bda 100644 +--- a/dlls/d3dx9_36/tests/shader.c ++++ b/dlls/d3dx9_36/tests/shader.c +@@ -6628,6 +6628,60 @@ if (0) + ok(semantics[0].UsageIndex == 0, "Got %u, expected 0\n", semantics[0].UsageIndex); + } + ++static const DWORD ps_tex[] = { ++ 0xffff0103, /* ps_1_3 */ ++ 0x00000042, 0xb00f0000, /* tex t0 */ ++ 0x00000000, /* nop */ ++ 0x0000ffff}; ++ ++static const DWORD ps_texld_1_4[] = { ++ 0xffff0104, /* ps_1_4 */ ++ 0x00000042, 0xb00f0000, 0xa0e40000, /* texld t0, c0 */ ++ 0x00000000, /* nop */ ++ 0x0000ffff}; ++ ++static const DWORD ps_texld_2_0[] = { ++ 0xffff0200, /* ps_2_0 */ ++ 0x00000042, 0xb00f0000, 0xa0e40000, 0xa0e40001, /* texld t0, c0, c1 */ ++ 0x00000000, /* nop */ ++ 0x0000ffff}; ++ ++static const DWORD ps_texcoord[] = { ++ 0xffff0103, /* ps_1_4 */ ++ 0x00000040, 0xb00f0000, /* texcoord t0 */ ++ 0x00000000, /* nop */ ++ 0x0000ffff}; ++ ++static const DWORD ps_texcrd[] = { ++ 0xffff0104, /* ps_2_0 */ ++ 0x00000040, 0xb00f0000, 0xa0e40000, /* texcrd t0, c0 */ ++ 0x00000000, /* nop */ ++ 0x0000ffff}; ++ ++static const DWORD ps_sincos_2_0[] = { ++ 0xffff0200, /* ps_2_0 */ ++ 0x00000025, 0xb00f0000, 0xa0e40000, 0xa0e40001, 0xa0e40002, /* sincos t0, c0, c1, c2 */ ++ 0x00000000, /* nop */ ++ 0x0000ffff}; ++ ++static const DWORD ps_sincos_3_0[] = { ++ 0xffff0300, /* ps_3_0 */ ++ 0x00000025, 0xb00f0000, 0xa0e40000, /* sincos t0, c0 */ ++ 0x00000000, /* nop */ ++ 0x0000ffff}; ++ ++static const DWORD vs_sincos_2_0[] = { ++ 0xfffe0200, /* vs_2_0 */ ++ 0x00000025, 0xb00f0000, 0xa0e40000, 0xa0e40001, 0xa0e40002, /* sincos a0, c0, c1, c2 */ ++ 0x00000000, /* nop */ ++ 0x0000ffff}; ++ ++static const DWORD vs_sincos_3_0[] = { ++ 0xfffe0300, /* vs_3_0 */ ++ 0x00000025, 0xb00f0000, 0xa0e40000, /* sincos a0, c0 */ ++ 0x00000000, /* nop */ ++ 0x0000ffff}; ++ + static void test_disassemble_shader(void) + { + static const char disasm_vs[] = " vs_1_1\n" +@@ -6642,6 +6696,33 @@ static void test_disassemble_shader(void) + " dp3 r0, c1, c0\n" + " mul r0, v0, r0\n" + " mul r0, t0, r0\n"; ++ static const char disasm_ps_tex[] = " ps_1_3\n" ++ " tex t0\n" ++ " nop\n"; ++ static const char disasm_ps_texld_1_4[] = " ps_1_4\n" ++ " texld t0, c0\n" ++ " nop\n"; ++ static const char disasm_ps_texld_2_0[] = " ps_2_0\n" ++ " texld t0, c0, c1\n" ++ " nop\n"; ++ static const char disasm_ps_texcoord[] = " ps_1_3\n" ++ " texcoord t0\n" ++ " nop\n"; ++ static const char disasm_ps_texcrd[] = " ps_1_4\n" ++ " texcrd t0, c0\n" ++ " nop\n"; ++ static const char disasm_ps_sincos_2_0[] = " ps_2_0\n" ++ " sincos t0, c0, c1, c2\n" ++ " nop\n"; ++ static const char disasm_ps_sincos_3_0[] = " ps_3_0\n" ++ " sincos t0, c0\n" ++ " nop\n"; ++ static const char disasm_vs_sincos_2_0[] = " vs_2_0\n" ++ " sincos a0, c0, c1, c2\n" ++ " nop\n"; ++ static const char disasm_vs_sincos_3_0[] = " vs_3_0\n" ++ " sincos a0, c0\n" ++ " nop\n"; + ID3DXBuffer *disassembly; + HRESULT ret; + char *ptr; +@@ -6671,6 +6752,88 @@ static void test_disassemble_shader(void) + ok(!memcmp(ptr, disasm_ps, sizeof(disasm_ps) - 1), /* compare beginning */ + "Returned '%s', expected '%s'\n", ptr, disasm_ps); + ID3DXBuffer_Release(disassembly); ++ ++ /* Test tex instruction with pixel shader 1.3 */ ++ disassembly = (void *)0xdeadbeef; ++ ret = D3DXDisassembleShader(ps_tex, FALSE, NULL, &disassembly); ++ ok(ret == D3D_OK, "Failed with %#x\n", ret); ++ ptr = ID3DXBuffer_GetBufferPointer(disassembly); ++ ok(!memcmp(ptr, disasm_ps_tex, sizeof(disasm_ps_tex) - 1), /* compare beginning */ ++ "Returned '%s', expected '%s'\n", ptr, disasm_ps_tex); ++ ID3DXBuffer_Release(disassembly); ++ ++ /* Test texld instruction with pixel shader 1.4 */ ++ disassembly = (void *)0xdeadbeef; ++ ret = D3DXDisassembleShader(ps_texld_1_4, FALSE, NULL, &disassembly); ++ ok(ret == D3D_OK, "Failed with %#x\n", ret); ++ ptr = ID3DXBuffer_GetBufferPointer(disassembly); ++ ok(!memcmp(ptr, disasm_ps_texld_1_4, sizeof(disasm_ps_texld_1_4) - 1), /* compare beginning */ ++ "Returned '%s', expected '%s'\n", ptr, disasm_ps_texld_1_4); ++ ID3DXBuffer_Release(disassembly); ++ ++ /* Test texld instruction with pixel shader 2.0 */ ++ disassembly = (void *)0xdeadbeef; ++ ret = D3DXDisassembleShader(ps_texld_2_0, FALSE, NULL, &disassembly); ++ ok(ret == D3D_OK, "Failed with %#x\n", ret); ++ ptr = ID3DXBuffer_GetBufferPointer(disassembly); ++ ok(!memcmp(ptr, disasm_ps_texld_2_0, sizeof(disasm_ps_texld_2_0) - 1), /* compare beginning */ ++ "Returned '%s', expected '%s'\n", ptr, disasm_ps_texld_2_0); ++ ID3DXBuffer_Release(disassembly); ++ ++ /* Test texcoord instruction with pixel shader 1.3 */ ++ disassembly = (void *)0xdeadbeef; ++ ret = D3DXDisassembleShader(ps_texcoord, FALSE, NULL, &disassembly); ++ ok(ret == D3D_OK, "Failed with %#x\n", ret); ++ ptr = ID3DXBuffer_GetBufferPointer(disassembly); ++ ok(!memcmp(ptr, disasm_ps_texcoord, sizeof(disasm_ps_texcoord) - 1), /* compare beginning */ ++ "Returned '%s', expected '%s'\n", ptr, disasm_ps_texcoord); ++ ID3DXBuffer_Release(disassembly); ++ ++ /* Test texcrd instruction with pixel shader 1.4 */ ++ disassembly = (void *)0xdeadbeef; ++ ret = D3DXDisassembleShader(ps_texcrd, FALSE, NULL, &disassembly); ++ ok(ret == D3D_OK, "Failed with %#x\n", ret); ++ ptr = ID3DXBuffer_GetBufferPointer(disassembly); ++ ok(!memcmp(ptr, disasm_ps_texcrd, sizeof(disasm_ps_texcrd) - 1), /* compare beginning */ ++ "Returned '%s', expected '%s'\n", ptr, disasm_ps_texcrd); ++ ID3DXBuffer_Release(disassembly); ++ ++ /* Test sincos instruction pixel shader 2.0 */ ++ disassembly = (void *)0xdeadbeef; ++ ret = D3DXDisassembleShader(ps_sincos_2_0, FALSE, NULL, &disassembly); ++ ok(ret == D3D_OK, "Failed with %#x\n", ret); ++ ptr = ID3DXBuffer_GetBufferPointer(disassembly); ++ ok(!memcmp(ptr, disasm_ps_sincos_2_0, sizeof(disasm_ps_sincos_2_0) - 1), /* compare beginning */ ++ "Returned '%s', expected '%s'\n", ptr, disasm_ps_sincos_2_0); ++ ID3DXBuffer_Release(disassembly); ++ ++ /* Test sincos instruction with pixel shader 3.0 */ ++ disassembly = (void *)0xdeadbeef; ++ ret = D3DXDisassembleShader(ps_sincos_3_0, FALSE, NULL, &disassembly); ++ ok(ret == D3D_OK, "Failed with %#x\n", ret); ++ ptr = ID3DXBuffer_GetBufferPointer(disassembly); ++ ok(!memcmp(ptr, disasm_ps_sincos_3_0, sizeof(disasm_ps_sincos_3_0) - 1), /* compare beginning */ ++ "Returned '%s', expected '%s'\n", ptr, disasm_ps_sincos_3_0); ++ ID3DXBuffer_Release(disassembly); ++ ++ /* Test sincos instruction with pixel shader 2.0 */ ++ disassembly = (void *)0xdeadbeef; ++ ret = D3DXDisassembleShader(vs_sincos_2_0, FALSE, NULL, &disassembly); ++ ok(ret == D3D_OK, "Failed with %#x\n", ret); ++ ptr = ID3DXBuffer_GetBufferPointer(disassembly); ++ ok(!memcmp(ptr, disasm_vs_sincos_2_0, sizeof(disasm_vs_sincos_2_0) - 1), /* compare beginning */ ++ "Returned '%s', expected '%s'\n", ptr, disasm_vs_sincos_2_0); ++ ID3DXBuffer_Release(disassembly); ++ ++ /* Test sincos instruction with pixel shader 3.0 */ ++ disassembly = (void *)0xdeadbeef; ++ ret = D3DXDisassembleShader(vs_sincos_3_0, FALSE, NULL, &disassembly); ++ ok(ret == D3D_OK, "Failed with %#x\n", ret); ++ ptr = ID3DXBuffer_GetBufferPointer(disassembly); ++ ok(!memcmp(ptr, disasm_vs_sincos_3_0, sizeof(disasm_vs_sincos_3_0) - 1), /* compare beginning */ ++ "Returned '%s', expected '%s'\n", ptr, disasm_vs_sincos_3_0); ++ ID3DXBuffer_Release(disassembly); ++ + } + + START_TEST(shader) +-- +2.7.1 + diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index d83fe57c..7f807432 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -3109,12 +3109,14 @@ if test "$enable_d3dx9_36_D3DXDisassembleShader" -eq 1; then patch_apply d3dx9_36-D3DXDisassembleShader/0003-d3dx9_36-Add-stub-for-D3DXFillCubeTextureTX.patch patch_apply d3dx9_36-D3DXDisassembleShader/0004-d3dx9_36-Implement-D3DXDisassembleShader.patch patch_apply d3dx9_36-D3DXDisassembleShader/0005-d3dx9_36-tests-Add-initial-tests-for-D3DXDisassemble.patch + patch_apply d3dx9_36-D3DXDisassembleShader/0006-d3dx9_36-tests-Add-additional-tests-for-special-case.patch ( echo '+ { "Christian Costa", "d3dx9_36: Implement D3DXCreateTextureShader with stubbed ID3DXTextureShader interface.", 1 },'; echo '+ { "Christian Costa", "include: Fix prototypes of D3DXFillXXXTextureTx for d3dx9.", 1 },'; echo '+ { "Christian Costa", "d3dx9_36: Add stub for D3DXFillCubeTextureTX.", 1 },'; - echo '+ { "Christian Costa", "d3dx9_36: Implement D3DXDisassembleShader.", 1 },'; + echo '+ { "Christian Costa", "d3dx9_36: Implement D3DXDisassembleShader.", 2 },'; echo '+ { "Sebastian Lackner", "d3dx9_36/tests: Add initial tests for D3DXDisassembleShader.", 1 },'; + echo '+ { "Christian Costa", "d3dx9_36/tests: Add additional tests for special cases.", 1 },'; ) >> "$patchlist" fi