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:
Ivan Gyurdiev 2006-05-17 02:02:36 -04:00 committed by Alexandre Julliard
parent 53d240a3e0
commit 404eff792f
4 changed files with 96 additions and 44 deletions

View File

@ -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, &param, &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) {

View File

@ -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) {

View File

@ -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) {

View File

@ -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));