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;
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
static inline int shader_skip_opcode(
|
||||
IWineD3DBaseShaderImpl* This,
|
||||
|
@ -99,6 +122,36 @@ static inline int shader_skip_opcode(
|
|||
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,
|
||||
* texUsed = addrUsed, and
|
||||
* D3DSPR_TEXTURE = D3DSPR_ADDR.
|
||||
|
@ -484,11 +537,9 @@ void generate_base_shader(
|
|||
curOpcode = shader_get_opcode(iface, opcode_token);
|
||||
|
||||
/* Unknown opcode and its parameters */
|
||||
if (NULL == curOpcode) {
|
||||
while (*pToken & 0x80000000) { /* TODO: Think of a sensible name for 0x80000000 */
|
||||
FIXME("unrecognized opcode: %08lx\n", *pToken);
|
||||
++pToken;
|
||||
}
|
||||
if (NULL == curOpcode) {
|
||||
FIXME("Unrecognized opcode: token=%08lX\n", opcode_token);
|
||||
pToken += shader_skip_unrecognized(iface, pToken);
|
||||
|
||||
/* Using GLSL & no generator function exists */
|
||||
} else if (USING_GLSL && curOpcode->hw_glsl_fct == NULL) {
|
||||
|
|
|
@ -1376,6 +1376,7 @@ HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface, C
|
|||
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
|
||||
const DWORD* pToken = pFunction;
|
||||
const SHADER_OPCODE *curOpcode = NULL;
|
||||
DWORD opcode_token;
|
||||
DWORD len = 0;
|
||||
DWORD i;
|
||||
TRACE("(%p) : Parsing programme\n", This);
|
||||
|
@ -1399,20 +1400,16 @@ HRESULT WINAPI IWineD3DPixelShaderImpl_SetFunction(IWineD3DPixelShader *iface, C
|
|||
if (!This->baseShader.version) {
|
||||
WARN("(%p) : pixel shader doesn't have a valid version identifier\n", This);
|
||||
}
|
||||
curOpcode = shader_get_opcode((IWineD3DBaseShader*) This, *pToken);
|
||||
++pToken;
|
||||
++len;
|
||||
opcode_token = *pToken++;
|
||||
curOpcode = shader_get_opcode((IWineD3DBaseShader*) This, opcode_token);
|
||||
len++;
|
||||
if (NULL == curOpcode) {
|
||||
int tokens_read;
|
||||
|
||||
/* TODO: Think of a good name for 0x80000000 and replace it with a constant */
|
||||
while (*pToken & 0x80000000) {
|
||||
|
||||
/* unknown current opcode ... */
|
||||
TRACE("unrecognized opcode: %08lx", *pToken);
|
||||
++pToken;
|
||||
++len;
|
||||
TRACE("\n");
|
||||
}
|
||||
FIXME("Unrecognized opcode: token=%08lX\n", opcode_token);
|
||||
tokens_read = shader_skip_unrecognized((IWineD3DBaseShader*) This, pToken);
|
||||
pToken += tokens_read;
|
||||
len += tokens_read;
|
||||
|
||||
} else {
|
||||
if (curOpcode->opcode == D3DSIO_DCL) {
|
||||
|
|
|
@ -1116,7 +1116,8 @@ BOOL IWineD3DVertexShaderImpl_ExecuteHAL(IWineD3DVertexShader* iface, WINEVSHADE
|
|||
|
||||
HRESULT WINAPI IWineD3DVertexShaderImpl_ExecuteSW(IWineD3DVertexShader* iface, WINEVSHADERINPUTDATA* input, WINEVSHADEROUTPUTDATA* output) {
|
||||
IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
|
||||
|
||||
DWORD opcode_token;
|
||||
|
||||
/** Vertex Shader Temporary Registers */
|
||||
WINED3DSHADERVECTOR R[12];
|
||||
/*D3DSHADERSCALAR A0;*/
|
||||
|
@ -1175,23 +1176,15 @@ HRESULT WINAPI IWineD3DVertexShaderImpl_ExecuteSW(IWineD3DVertexShader* iface, W
|
|||
pToken += comment_len;
|
||||
continue ;
|
||||
}
|
||||
curOpcode = shader_get_opcode((IWineD3DBaseShader*) This, *pToken);
|
||||
++pToken;
|
||||
|
||||
opcode_token = *pToken++;
|
||||
curOpcode = shader_get_opcode((IWineD3DBaseShader*) This, opcode_token);
|
||||
|
||||
if (NULL == curOpcode) {
|
||||
i = 0;
|
||||
/* unknown current opcode ... */
|
||||
/* 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;
|
||||
}
|
||||
FIXME("Unrecognized opcode: token=%08lX\n", opcode_token);
|
||||
pToken += shader_skip_unrecognized((IWineD3DBaseShader*) This, pToken);
|
||||
/* return FALSE; */
|
||||
|
||||
} else {
|
||||
if (curOpcode->num_params > 0) {
|
||||
/* 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;
|
||||
const DWORD* pToken = pFunction;
|
||||
const SHADER_OPCODE* curOpcode = NULL;
|
||||
DWORD opcode_token;
|
||||
DWORD len = 0;
|
||||
DWORD i;
|
||||
TRACE("(%p) : Parsing programme\n", This);
|
||||
|
@ -1531,18 +1525,18 @@ HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader *iface,
|
|||
len += comment_len + 1;
|
||||
continue;
|
||||
}
|
||||
curOpcode = shader_get_opcode((IWineD3DBaseShader*) This, *pToken);
|
||||
++pToken;
|
||||
++len;
|
||||
|
||||
opcode_token = *pToken++;
|
||||
curOpcode = shader_get_opcode((IWineD3DBaseShader*) This, opcode_token);
|
||||
len++;
|
||||
|
||||
if (NULL == curOpcode) {
|
||||
/* TODO: Think of a good name for 0x80000000 and replace it with a constant */
|
||||
while (*pToken & 0x80000000) {
|
||||
/* unknown current opcode ... */
|
||||
FIXME("unrecognized opcode: %08lx", *pToken);
|
||||
++pToken;
|
||||
++len;
|
||||
TRACE("\n");
|
||||
}
|
||||
int tokens_read;
|
||||
|
||||
FIXME("Unrecognized opcode: token=%08lX\n", opcode_token);
|
||||
tokens_read = shader_skip_unrecognized((IWineD3DBaseShader*) This, pToken);
|
||||
pToken += tokens_read;
|
||||
len += tokens_read;
|
||||
|
||||
} else {
|
||||
if (curOpcode->opcode == D3DSIO_DCL) {
|
||||
|
|
|
@ -1372,6 +1372,16 @@ extern void shader_dump_param(
|
|||
const DWORD param,
|
||||
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) {
|
||||
return (((param & D3DSP_REGTYPE_MASK) >> D3DSP_REGTYPE_SHIFT) |
|
||||
((param & D3DSP_REGTYPE_MASK2) >> D3DSP_REGTYPE_SHIFT2));
|
||||
|
|
Loading…
Reference in New Issue