[WINED3D 4/9] Register map cleanups
Ivan Gyurdiev
ivg231 at gmail.com
Mon Jun 12 01:55:30 CDT 2006
Various cleanups:
- do not use DWORD as a bitmask, that places artificial limit of 32 on
registers
- track attributes that are used and declare only those
- move declarations function call in pshader/vshader to allow us to
insert pixel or vertex specific code between the declarations and the
rest of the code
- remove redundant 0 intializers
- remove useless continue statement
-------------- next part --------------
---
dlls/wined3d/baseshader.c | 64 +++++++++++++++++++---------------------
dlls/wined3d/pixelshader.c | 6 ++++
dlls/wined3d/vertexshader.c | 6 ++++
dlls/wined3d/wined3d_private.h | 32 ++++++++++++++++----
4 files changed, 67 insertions(+), 41 deletions(-)
7a198e7c28fddc0b35a621ba43d1b72f7587b2d8
diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c
index 774c313..6f53ce2 100644
--- a/dlls/wined3d/baseshader.c
+++ b/dlls/wined3d/baseshader.c
@@ -299,13 +299,12 @@ void shader_get_registers_used(
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
+ /* There are some minor differences between pixel and vertex shaders */
+ char pshader = shader_is_pshader_version(This->baseShader.hex_version);
+
if (pToken == NULL)
return;
- reg_maps->temporary = 0;
- reg_maps->texcoord = 0;
- reg_maps->address = 0;
-
while (D3DVS_END() != *pToken) {
CONST SHADER_OPCODE* curOpcode;
DWORD opcode_token;
@@ -331,7 +330,6 @@ void shader_get_registers_used(
if (NULL == curOpcode) {
while (*pToken & 0x80000000)
++pToken;
- continue;
/* Handle declarations */
} else if (D3DSIO_DCL == curOpcode->opcode) {
@@ -339,8 +337,13 @@ void shader_get_registers_used(
DWORD usage = *pToken++;
DWORD param = *pToken++;
DWORD regtype = shader_get_regtype(param);
+ unsigned int regnum = param & D3DSP_REGNUM_MASK;
if (D3DSPR_INPUT == regtype) {
+
+ if (!pshader)
+ reg_maps->attributes[regnum] = 1;
+
shader_parse_decl_usage(reg_maps->semantics_in, usage, param);
} else if (D3DSPR_OUTPUT == regtype) {
@@ -352,7 +355,6 @@ void shader_get_registers_used(
/* Skip definitions (for now) */
} else if (D3DSIO_DEF == curOpcode->opcode) {
pToken += curOpcode->num_params;
- continue;
/* Set texture registers, and temporary registers */
} else {
@@ -378,14 +380,17 @@ void shader_get_registers_used(
if (D3DSPR_TEXTURE == regtype) { /* vs: D3DSPR_ADDR */
- if (shader_is_pshader_version(This->baseShader.hex_version))
- reg_maps->texcoord |= (1 << reg);
+ if (pshader)
+ reg_maps->texcoord[reg] = 1;
else
- reg_maps->address |= (1 << reg);
+ reg_maps->address[reg] = 1;
}
- if (D3DSPR_TEMP == regtype)
- reg_maps->temporary |= (1 << reg);
+ else if (D3DSPR_TEMP == regtype)
+ reg_maps->temporary[reg] = 1;
+
+ else if (D3DSPR_INPUT == regtype && !pshader)
+ reg_maps->attributes[reg] = 1;
}
}
}
@@ -651,9 +656,8 @@ void shader_dump_param(
}
}
-/** Generate the variable & register declarations for the ARB_vertex_program
- output target */
-void generate_arb_declarations(
+/* Generate the variable & register declarations for the ARB_vertex_program output target */
+void shader_generate_arb_declarations(
IWineD3DBaseShader *iface,
shader_reg_maps* reg_maps,
SHADER_BUFFER* buffer) {
@@ -662,23 +666,23 @@ void generate_arb_declarations(
DWORD i;
for(i = 0; i < This->baseShader.limits.temporary; i++) {
- if (reg_maps->temporary & (1 << i))
+ if (reg_maps->temporary[i])
shader_addline(buffer, "TEMP R%lu;\n", i);
}
for (i = 0; i < This->baseShader.limits.address; i++) {
- if (reg_maps->address & (1 << i))
+ if (reg_maps->address[i])
shader_addline(buffer, "ADDRESS A%ld;\n", i);
}
for(i = 0; i < This->baseShader.limits.texture; i++) {
- if (reg_maps->texcoord & (1 << i))
+ if (reg_maps->texcoord[i])
shader_addline(buffer,"TEMP T%lu;\n", i);
}
/* Texture coordinate registers must be pre-loaded */
for (i = 0; i < This->baseShader.limits.texture; i++) {
- if (reg_maps->texcoord & (1 << i))
+ if (reg_maps->texcoord[i])
shader_addline(buffer, "MOV T%lu, fragment.texcoord[%lu];\n", i, i);
}
@@ -688,9 +692,8 @@ void generate_arb_declarations(
This->baseShader.limits.constant_float - 1);
}
-/** Generate the variable & register declarations for the GLSL
- output target */
-void generate_glsl_declarations(
+/** Generate the variable & register declarations for the GLSL output target */
+void shader_generate_glsl_declarations(
IWineD3DBaseShader *iface,
shader_reg_maps* reg_maps,
SHADER_BUFFER* buffer) {
@@ -711,25 +714,25 @@ void generate_glsl_declarations(
/* Declare address variables */
for (i = 0; i < This->baseShader.limits.address; i++) {
- if (reg_maps->address & (1 << i))
+ if (reg_maps->address[i])
shader_addline(buffer, "ivec4 A%ld;\n", i);
}
- /* Declare texture temporaries */
+ /* Declare texture coordinate temporaries and initialize them */
for (i = 0; i < This->baseShader.limits.texture; i++) {
shader_addline(buffer, "vec4 T%lu = gl_TexCoord[%lu];\n", i, i);
}
/* Declare temporary variables */
for(i = 0; i < This->baseShader.limits.temporary; i++) {
- if (reg_maps->temporary & (1 << i))
+ if (reg_maps->temporary[i])
shader_addline(buffer, "vec4 R%lu;\n", i);
}
- /* Declare all named attributes (TODO: Add this to the reg_maps
- * and only declare those that are needed) */
+ /* Declare attributes */
for (i = 0; i < This->baseShader.limits.attributes; i++) {
- shader_addline(buffer, "attribute vec4 attrib%i;\n", i);
+ if (reg_maps->attributes[i])
+ shader_addline(buffer, "attribute vec4 attrib%i;\n", i);
}
/* Temporary variables for matrix operations */
@@ -765,13 +768,6 @@ void shader_generate_main(
hw_arg.reg_maps = reg_maps;
This->baseShader.parse_state.current_row = 0;
- /* Pre-declare registers */
- if (wined3d_settings.shader_mode == SHADER_GLSL) {
- generate_glsl_declarations(iface, reg_maps, buffer);
- } else {
- generate_arb_declarations(iface, reg_maps, buffer);
- }
-
/* Second pass, process opcodes */
if (NULL != pToken) {
while (D3DPS_END() != *pToken) {
diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c
index 055cf0d..7312811 100644
--- a/dlls/wined3d/pixelshader.c
+++ b/dlls/wined3d/pixelshader.c
@@ -1333,6 +1333,9 @@ #endif
/* Create the hw GLSL shader object and assign it as the baseShader.prgId */
GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB));
+ /* Base Declarations */
+ shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, ®_maps, &buffer);
+
/* Base Shader Body */
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, ®_maps, pFunction);
@@ -1362,6 +1365,9 @@ #endif
shader_addline(&buffer, "PARAM coefmul = { 2, 4, 8, 16 };\n");
shader_addline(&buffer, "PARAM one = { 1.0, 1.0, 1.0, 1.0 };\n");
+ /* Base Declarations */
+ shader_generate_arb_declarations( (IWineD3DBaseShader*) This, ®_maps, &buffer);
+
/* Base Shader Body */
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, ®_maps, pFunction);
diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c
index 3d7db4d..c116595 100644
--- a/dlls/wined3d/vertexshader.c
+++ b/dlls/wined3d/vertexshader.c
@@ -864,6 +864,9 @@ #endif
/* Create the hw GLSL shader program and assign it as the baseShader.prgId */
GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
+ /* Base Declarations */
+ shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, ®_maps, &buffer);
+
/* Base Shader Body */
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, ®_maps, pFunction);
@@ -887,6 +890,9 @@ #endif
This->baseShader.limits.constant_float =
min(95, This->baseShader.limits.constant_float);
+ /* Base Declarations */
+ shader_generate_arb_declarations( (IWineD3DBaseShader*) This, ®_maps, &buffer);
+
/* Base Shader Body */
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, ®_maps, pFunction);
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 8b67a7e..91c0082 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1248,17 +1248,25 @@ struct glsl_shader_prog_link {
IWineD3DPixelShader* pixelShader;
};
+/* TODO: Make this dynamic, based on shader limits ? */
+#define MAX_REG_ADDR 1
+#define MAX_REG_TEMP 32
+#define MAX_REG_TEXCRD 8
+#define MAX_ATTRIBS 16
+#define MAX_CONST_F 256
+
typedef struct shader_reg_maps {
- DWORD texcoord;
- DWORD temporary;
- DWORD address;
- /* Constants */
- CHAR constantsF[256]; /* TODO: Make this dynamic */
+ char texcoord[MAX_REG_TEXCRD]; /* pixel < 3.0 */
+ char temporary[MAX_REG_TEMP]; /* pixel, vertex */
+ char address[MAX_REG_ADDR]; /* vertex */
+ char attributes[MAX_ATTRIBS]; /* vertex */
+
+ char constantsF[MAX_CONST_F]; /* pixel, vertex */
/* TODO: Integer and bool constants */
- DWORD* semantics_in;
- DWORD* semantics_out;
+ DWORD* semantics_in; /* vertex, pixel */
+ DWORD* semantics_out; /* vertex */
} shader_reg_maps;
@@ -1373,6 +1381,16 @@ extern void shader_get_registers_used(
shader_reg_maps* reg_maps,
CONST DWORD* pToken);
+extern void shader_generate_glsl_declarations(
+ IWineD3DBaseShader *iface,
+ shader_reg_maps* reg_maps,
+ SHADER_BUFFER* buffer);
+
+extern void shader_generate_arb_declarations(
+ IWineD3DBaseShader *iface,
+ shader_reg_maps* reg_maps,
+ SHADER_BUFFER* buffer);
+
extern void shader_generate_main(
IWineD3DBaseShader *iface,
SHADER_BUFFER* buffer,
--
1.3.3
More information about the wine-patches
mailing list