wined3d: Add shader_get_param() fn, which processes address tokens.
Add a new function to process parameters. On shaders 1.0, processing parameters amounts to *pToken++. On shaders 2.0+, we have a relative addressing token to account for. This function should be used, instead of relying on num_params everywhere.
This commit is contained in:
parent
53d240a3e0
commit
404eff792f
|
@ -85,6 +85,29 @@ const SHADER_OPCODE* shader_get_opcode(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Read a parameter opcode from the input stream,
|
||||||
|
* and possibly a relative addressing token.
|
||||||
|
* Return the number of tokens read */
|
||||||
|
int shader_get_param(
|
||||||
|
IWineD3DBaseShader* iface,
|
||||||
|
const DWORD* pToken,
|
||||||
|
DWORD* param,
|
||||||
|
DWORD* addr_token) {
|
||||||
|
|
||||||
|
/* PS >= 3.0 have relative addressing (with token)
|
||||||
|
* VS >= 2.0 have relative addressing (with token)
|
||||||
|
* VS >= 1.0 < 2.0 have relative addressing (without token)
|
||||||
|
* The version check below should work in general */
|
||||||
|
|
||||||
|
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
|
||||||
|
char rel_token = D3DSHADER_VERSION_MAJOR(This->baseShader.hex_version) >= 2 &&
|
||||||
|
((*pToken & D3DSHADER_ADDRESSMODE_MASK) == D3DSHADER_ADDRMODE_RELATIVE);
|
||||||
|
|
||||||
|
*param = *pToken;
|
||||||
|
*addr_token = rel_token? *(pToken + 1): 0;
|
||||||
|
return rel_token? 2:1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Return the number of parameters to skip for an opcode */
|
/* Return the number of parameters to skip for an opcode */
|
||||||
static inline int shader_skip_opcode(
|
static inline int shader_skip_opcode(
|
||||||
IWineD3DBaseShaderImpl* This,
|
IWineD3DBaseShaderImpl* This,
|
||||||
|
@ -99,6 +122,36 @@ static inline int shader_skip_opcode(
|
||||||
curOpcode->num_params;
|
curOpcode->num_params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Read the parameters of an unrecognized opcode from the input stream
|
||||||
|
* Return the number of tokens read.
|
||||||
|
*
|
||||||
|
* Note: This function assumes source or destination token format.
|
||||||
|
* It will not work with specially-formatted tokens like DEF or DCL,
|
||||||
|
* but hopefully those would be recognized */
|
||||||
|
|
||||||
|
int shader_skip_unrecognized(
|
||||||
|
IWineD3DBaseShader* iface,
|
||||||
|
const DWORD* pToken) {
|
||||||
|
|
||||||
|
int tokens_read = 0;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
/* TODO: Think of a good name for 0x80000000 and replace it with a constant */
|
||||||
|
while (*pToken & 0x80000000) {
|
||||||
|
|
||||||
|
DWORD param, addr_token;
|
||||||
|
tokens_read += shader_get_param(iface, pToken, ¶m, &addr_token);
|
||||||
|
pToken += tokens_read;
|
||||||
|
|
||||||
|
FIXME("Unrecognized opcode param: token=%08lX "
|
||||||
|
"addr_token=%08lX name=", param, addr_token);
|
||||||
|
shader_dump_param(iface, param, i);
|
||||||
|
FIXME("\n");
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
return tokens_read;
|
||||||
|
}
|
||||||
|
|
||||||
/* Note: For vertex shaders,
|
/* Note: For vertex shaders,
|
||||||
* texUsed = addrUsed, and
|
* texUsed = addrUsed, and
|
||||||
* D3DSPR_TEXTURE = D3DSPR_ADDR.
|
* D3DSPR_TEXTURE = D3DSPR_ADDR.
|
||||||
|
@ -484,11 +537,9 @@ void generate_base_shader(
|
||||||
curOpcode = shader_get_opcode(iface, opcode_token);
|
curOpcode = shader_get_opcode(iface, opcode_token);
|
||||||
|
|
||||||
/* Unknown opcode and its parameters */
|
/* Unknown opcode and its parameters */
|
||||||
if (NULL == curOpcode) {
|
if (NULL == curOpcode) {
|
||||||
while (*pToken & 0x80000000) { /* TODO: Think of a sensible name for 0x80000000 */
|
FIXME("Unrecognized opcode: token=%08lX\n", opcode_token);
|
||||||
FIXME("unrecognized opcode: %08lx\n", *pToken);
|
pToken += shader_skip_unrecognized(iface, pToken);
|
||||||
++pToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Using GLSL & no generator function exists */
|
/* Using GLSL & no generator function exists */
|
||||||
} else if (USING_GLSL && curOpcode->hw_glsl_fct == NULL) {
|
} else if (USING_GLSL && curOpcode->hw_glsl_fct == NULL) {
|
||||||
|
|
|
@ -1376,6 +1376,7 @@ HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface, C
|
||||||
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
|
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
|
||||||
const DWORD* pToken = pFunction;
|
const DWORD* pToken = pFunction;
|
||||||
const SHADER_OPCODE *curOpcode = NULL;
|
const SHADER_OPCODE *curOpcode = NULL;
|
||||||
|
DWORD opcode_token;
|
||||||
DWORD len = 0;
|
DWORD len = 0;
|
||||||
DWORD i;
|
DWORD i;
|
||||||
TRACE("(%p) : Parsing programme\n", This);
|
TRACE("(%p) : Parsing programme\n", This);
|
||||||
|
@ -1399,20 +1400,16 @@ HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface, C
|
||||||
if (!This->baseShader.version) {
|
if (!This->baseShader.version) {
|
||||||
WARN("(%p) : pixel shader doesn't have a valid version identifier\n", This);
|
WARN("(%p) : pixel shader doesn't have a valid version identifier\n", This);
|
||||||
}
|
}
|
||||||
curOpcode = shader_get_opcode((IWineD3DBaseShader*) This, *pToken);
|
opcode_token = *pToken++;
|
||||||
++pToken;
|
curOpcode = shader_get_opcode((IWineD3DBaseShader*) This, opcode_token);
|
||||||
++len;
|
len++;
|
||||||
if (NULL == curOpcode) {
|
if (NULL == curOpcode) {
|
||||||
|
int tokens_read;
|
||||||
|
|
||||||
/* TODO: Think of a good name for 0x80000000 and replace it with a constant */
|
FIXME("Unrecognized opcode: token=%08lX\n", opcode_token);
|
||||||
while (*pToken & 0x80000000) {
|
tokens_read = shader_skip_unrecognized((IWineD3DBaseShader*) This, pToken);
|
||||||
|
pToken += tokens_read;
|
||||||
/* unknown current opcode ... */
|
len += tokens_read;
|
||||||
TRACE("unrecognized opcode: %08lx", *pToken);
|
|
||||||
++pToken;
|
|
||||||
++len;
|
|
||||||
TRACE("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (curOpcode->opcode == D3DSIO_DCL) {
|
if (curOpcode->opcode == D3DSIO_DCL) {
|
||||||
|
|
|
@ -1116,6 +1116,7 @@ BOOL IWineD3DVertexShaderImpl_ExecuteHAL(IWineD3DVertexShader* iface, WINEVSHADE
|
||||||
|
|
||||||
HRESULT WINAPI IWineD3DVertexShaderImpl_ExecuteSW(IWineD3DVertexShader* iface, WINEVSHADERINPUTDATA* input, WINEVSHADEROUTPUTDATA* output) {
|
HRESULT WINAPI IWineD3DVertexShaderImpl_ExecuteSW(IWineD3DVertexShader* iface, WINEVSHADERINPUTDATA* input, WINEVSHADEROUTPUTDATA* output) {
|
||||||
IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
|
IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
|
||||||
|
DWORD opcode_token;
|
||||||
|
|
||||||
/** Vertex Shader Temporary Registers */
|
/** Vertex Shader Temporary Registers */
|
||||||
WINED3DSHADERVECTOR R[12];
|
WINED3DSHADERVECTOR R[12];
|
||||||
|
@ -1175,23 +1176,15 @@ HRESULT WINAPI IWineD3DVertexShaderImpl_ExecuteSW(IWineD3DVertexShader* iface, W
|
||||||
pToken += comment_len;
|
pToken += comment_len;
|
||||||
continue ;
|
continue ;
|
||||||
}
|
}
|
||||||
curOpcode = shader_get_opcode((IWineD3DBaseShader*) This, *pToken);
|
|
||||||
++pToken;
|
opcode_token = *pToken++;
|
||||||
|
curOpcode = shader_get_opcode((IWineD3DBaseShader*) This, opcode_token);
|
||||||
|
|
||||||
if (NULL == curOpcode) {
|
if (NULL == curOpcode) {
|
||||||
i = 0;
|
FIXME("Unrecognized opcode: token=%08lX\n", opcode_token);
|
||||||
/* unknown current opcode ... */
|
pToken += shader_skip_unrecognized((IWineD3DBaseShader*) This, pToken);
|
||||||
/* TODO: Think of a name for 0x80000000 and replace its use with a constant */
|
|
||||||
while (*pToken & 0x80000000) {
|
|
||||||
if (i == 0) {
|
|
||||||
FIXME("unrecognized opcode: pos=%d token=%08lX\n", (pToken - 1) - This->baseShader.function, *(pToken - 1));
|
|
||||||
}
|
|
||||||
FIXME("unrecognized opcode param: pos=%d token=%08lX what=", pToken - This->baseShader.function, *pToken);
|
|
||||||
shader_dump_param((IWineD3DBaseShader*) This, *pToken, i);
|
|
||||||
TRACE("\n");
|
|
||||||
++i;
|
|
||||||
++pToken;
|
|
||||||
}
|
|
||||||
/* return FALSE; */
|
/* return FALSE; */
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (curOpcode->num_params > 0) {
|
if (curOpcode->num_params > 0) {
|
||||||
/* TRACE(">> execting opcode: pos=%d opcode_name=%s token=%08lX\n", pToken - vshader->function, curOpcode->name, *pToken); */
|
/* TRACE(">> execting opcode: pos=%d opcode_name=%s token=%08lX\n", pToken - vshader->function, curOpcode->name, *pToken); */
|
||||||
|
@ -1505,6 +1498,7 @@ HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader *iface,
|
||||||
IWineD3DVertexShaderImpl *This =(IWineD3DVertexShaderImpl *)iface;
|
IWineD3DVertexShaderImpl *This =(IWineD3DVertexShaderImpl *)iface;
|
||||||
const DWORD* pToken = pFunction;
|
const DWORD* pToken = pFunction;
|
||||||
const SHADER_OPCODE* curOpcode = NULL;
|
const SHADER_OPCODE* curOpcode = NULL;
|
||||||
|
DWORD opcode_token;
|
||||||
DWORD len = 0;
|
DWORD len = 0;
|
||||||
DWORD i;
|
DWORD i;
|
||||||
TRACE("(%p) : Parsing programme\n", This);
|
TRACE("(%p) : Parsing programme\n", This);
|
||||||
|
@ -1531,18 +1525,18 @@ HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader *iface,
|
||||||
len += comment_len + 1;
|
len += comment_len + 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
curOpcode = shader_get_opcode((IWineD3DBaseShader*) This, *pToken);
|
|
||||||
++pToken;
|
opcode_token = *pToken++;
|
||||||
++len;
|
curOpcode = shader_get_opcode((IWineD3DBaseShader*) This, opcode_token);
|
||||||
|
len++;
|
||||||
|
|
||||||
if (NULL == curOpcode) {
|
if (NULL == curOpcode) {
|
||||||
/* TODO: Think of a good name for 0x80000000 and replace it with a constant */
|
int tokens_read;
|
||||||
while (*pToken & 0x80000000) {
|
|
||||||
/* unknown current opcode ... */
|
FIXME("Unrecognized opcode: token=%08lX\n", opcode_token);
|
||||||
FIXME("unrecognized opcode: %08lx", *pToken);
|
tokens_read = shader_skip_unrecognized((IWineD3DBaseShader*) This, pToken);
|
||||||
++pToken;
|
pToken += tokens_read;
|
||||||
++len;
|
len += tokens_read;
|
||||||
TRACE("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (curOpcode->opcode == D3DSIO_DCL) {
|
if (curOpcode->opcode == D3DSIO_DCL) {
|
||||||
|
|
|
@ -1372,6 +1372,16 @@ extern void shader_dump_param(
|
||||||
const DWORD param,
|
const DWORD param,
|
||||||
int input);
|
int input);
|
||||||
|
|
||||||
|
extern int shader_get_param(
|
||||||
|
IWineD3DBaseShader* iface,
|
||||||
|
const DWORD* pToken,
|
||||||
|
DWORD* param,
|
||||||
|
DWORD* addr_token);
|
||||||
|
|
||||||
|
extern int shader_skip_unrecognized(
|
||||||
|
IWineD3DBaseShader* iface,
|
||||||
|
const DWORD* pToken);
|
||||||
|
|
||||||
inline static int shader_get_regtype(const DWORD param) {
|
inline static int shader_get_regtype(const DWORD param) {
|
||||||
return (((param & D3DSP_REGTYPE_MASK) >> D3DSP_REGTYPE_SHIFT) |
|
return (((param & D3DSP_REGTYPE_MASK) >> D3DSP_REGTYPE_SHIFT) |
|
||||||
((param & D3DSP_REGTYPE_MASK2) >> D3DSP_REGTYPE_SHIFT2));
|
((param & D3DSP_REGTYPE_MASK2) >> D3DSP_REGTYPE_SHIFT2));
|
||||||
|
|
Loading…
Reference in New Issue