Commit a42925ee authored by Ivan Gyurdiev's avatar Ivan Gyurdiev Committed by Alexandre Julliard

wined3d: Register map cleanups.

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
parent 17b0d26c
......@@ -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) {
......
......@@ -1333,6 +1333,9 @@ inline static VOID IWineD3DPixelShaderImpl_GenerateShader(
/* 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, &reg_maps, &buffer);
/* Base Shader Body */
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, &reg_maps, pFunction);
......@@ -1362,6 +1365,9 @@ inline static VOID IWineD3DPixelShaderImpl_GenerateShader(
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, &reg_maps, &buffer);
/* Base Shader Body */
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, &reg_maps, pFunction);
......
......@@ -864,6 +864,9 @@ inline static VOID IWineD3DVertexShaderImpl_GenerateShader(
/* 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, &reg_maps, &buffer);
/* Base Shader Body */
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, &reg_maps, pFunction);
......@@ -887,6 +890,9 @@ inline static VOID IWineD3DVertexShaderImpl_GenerateShader(
This->baseShader.limits.constant_float =
min(95, This->baseShader.limits.constant_float);
/* Base Declarations */
shader_generate_arb_declarations( (IWineD3DBaseShader*) This, &reg_maps, &buffer);
/* Base Shader Body */
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, &reg_maps, pFunction);
......
......@@ -1247,17 +1247,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;
......@@ -1372,6 +1380,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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment