[WINED3D 5/11] Add shader_get_param() fn, which processes address
tokens
Ivan Gyurdiev
ivg2 at cornell.edu
Wed May 17 01:02:36 CDT 2006
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.
Add a shared skip_unrecognized() function as its first user.
This was taken from the software shaders handling, since I liked
how it printed out all the parameters. Make it addr_token aware.
-------------- next part --------------
---
dlls/wined3d/baseshader.c | 61 +++++++++++++++++++++++++++++++++++++---
dlls/wined3d/pixelshader.c | 21 ++++++--------
dlls/wined3d/vertexshader.c | 48 ++++++++++++++-----------------
dlls/wined3d/wined3d_private.h | 10 +++++++
4 files changed, 96 insertions(+), 44 deletions(-)
23e9e05ee3b3cee5bb3c7d76bcbb1c288fba382e
diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c
index 6ea5e9d..abf5019 100644
--- a/dlls/wined3d/baseshader.c
+++ b/dlls/wined3d/baseshader.c
@@ -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) {
diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c
index 0547105..9f0e1ee 100644
--- a/dlls/wined3d/pixelshader.c
+++ b/dlls/wined3d/pixelshader.c
@@ -1376,6 +1376,7 @@ HRESULT WINAPI IWineD3DPixelShaderImpl_S
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_S
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) {
diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c
index 9e7c38c..9fc34f5 100644
--- a/dlls/wined3d/vertexshader.c
+++ b/dlls/wined3d/vertexshader.c
@@ -1116,7 +1116,8 @@ BOOL IWineD3DVertexShaderImpl_ExecuteHAL
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 @@ #endif
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_
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_
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) {
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index aa875e6..34d512e 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -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));
--
1.3.1
More information about the wine-patches
mailing list