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( ...@@ -299,13 +299,12 @@ void shader_get_registers_used(
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface; 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) if (pToken == NULL)
return; return;
reg_maps->temporary = 0;
reg_maps->texcoord = 0;
reg_maps->address = 0;
while (D3DVS_END() != *pToken) { while (D3DVS_END() != *pToken) {
CONST SHADER_OPCODE* curOpcode; CONST SHADER_OPCODE* curOpcode;
DWORD opcode_token; DWORD opcode_token;
...@@ -331,7 +330,6 @@ void shader_get_registers_used( ...@@ -331,7 +330,6 @@ void shader_get_registers_used(
if (NULL == curOpcode) { if (NULL == curOpcode) {
while (*pToken & 0x80000000) while (*pToken & 0x80000000)
++pToken; ++pToken;
continue;
/* Handle declarations */ /* Handle declarations */
} else if (D3DSIO_DCL == curOpcode->opcode) { } else if (D3DSIO_DCL == curOpcode->opcode) {
...@@ -339,8 +337,13 @@ void shader_get_registers_used( ...@@ -339,8 +337,13 @@ void shader_get_registers_used(
DWORD usage = *pToken++; DWORD usage = *pToken++;
DWORD param = *pToken++; DWORD param = *pToken++;
DWORD regtype = shader_get_regtype(param); DWORD regtype = shader_get_regtype(param);
unsigned int regnum = param & D3DSP_REGNUM_MASK;
if (D3DSPR_INPUT == regtype) { if (D3DSPR_INPUT == regtype) {
if (!pshader)
reg_maps->attributes[regnum] = 1;
shader_parse_decl_usage(reg_maps->semantics_in, usage, param); shader_parse_decl_usage(reg_maps->semantics_in, usage, param);
} else if (D3DSPR_OUTPUT == regtype) { } else if (D3DSPR_OUTPUT == regtype) {
...@@ -352,7 +355,6 @@ void shader_get_registers_used( ...@@ -352,7 +355,6 @@ void shader_get_registers_used(
/* Skip definitions (for now) */ /* Skip definitions (for now) */
} else if (D3DSIO_DEF == curOpcode->opcode) { } else if (D3DSIO_DEF == curOpcode->opcode) {
pToken += curOpcode->num_params; pToken += curOpcode->num_params;
continue;
/* Set texture registers, and temporary registers */ /* Set texture registers, and temporary registers */
} else { } else {
...@@ -378,14 +380,17 @@ void shader_get_registers_used( ...@@ -378,14 +380,17 @@ void shader_get_registers_used(
if (D3DSPR_TEXTURE == regtype) { /* vs: D3DSPR_ADDR */ if (D3DSPR_TEXTURE == regtype) { /* vs: D3DSPR_ADDR */
if (shader_is_pshader_version(This->baseShader.hex_version)) if (pshader)
reg_maps->texcoord |= (1 << reg); reg_maps->texcoord[reg] = 1;
else else
reg_maps->address |= (1 << reg); reg_maps->address[reg] = 1;
} }
if (D3DSPR_TEMP == regtype) else if (D3DSPR_TEMP == regtype)
reg_maps->temporary |= (1 << reg); reg_maps->temporary[reg] = 1;
else if (D3DSPR_INPUT == regtype && !pshader)
reg_maps->attributes[reg] = 1;
} }
} }
} }
...@@ -651,9 +656,8 @@ void shader_dump_param( ...@@ -651,9 +656,8 @@ void shader_dump_param(
} }
} }
/** Generate the variable & register declarations for the ARB_vertex_program /* Generate the variable & register declarations for the ARB_vertex_program output target */
output target */ void shader_generate_arb_declarations(
void generate_arb_declarations(
IWineD3DBaseShader *iface, IWineD3DBaseShader *iface,
shader_reg_maps* reg_maps, shader_reg_maps* reg_maps,
SHADER_BUFFER* buffer) { SHADER_BUFFER* buffer) {
...@@ -662,23 +666,23 @@ void generate_arb_declarations( ...@@ -662,23 +666,23 @@ void generate_arb_declarations(
DWORD i; DWORD i;
for(i = 0; i < This->baseShader.limits.temporary; 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); shader_addline(buffer, "TEMP R%lu;\n", i);
} }
for (i = 0; i < This->baseShader.limits.address; 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); shader_addline(buffer, "ADDRESS A%ld;\n", i);
} }
for(i = 0; i < This->baseShader.limits.texture; 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); shader_addline(buffer,"TEMP T%lu;\n", i);
} }
/* Texture coordinate registers must be pre-loaded */ /* Texture coordinate registers must be pre-loaded */
for (i = 0; i < This->baseShader.limits.texture; i++) { 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); shader_addline(buffer, "MOV T%lu, fragment.texcoord[%lu];\n", i, i);
} }
...@@ -688,9 +692,8 @@ void generate_arb_declarations( ...@@ -688,9 +692,8 @@ void generate_arb_declarations(
This->baseShader.limits.constant_float - 1); This->baseShader.limits.constant_float - 1);
} }
/** Generate the variable & register declarations for the GLSL /** Generate the variable & register declarations for the GLSL output target */
output target */ void shader_generate_glsl_declarations(
void generate_glsl_declarations(
IWineD3DBaseShader *iface, IWineD3DBaseShader *iface,
shader_reg_maps* reg_maps, shader_reg_maps* reg_maps,
SHADER_BUFFER* buffer) { SHADER_BUFFER* buffer) {
...@@ -711,25 +714,25 @@ void generate_glsl_declarations( ...@@ -711,25 +714,25 @@ void generate_glsl_declarations(
/* Declare address variables */ /* Declare address variables */
for (i = 0; i < This->baseShader.limits.address; i++) { 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); 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++) { for (i = 0; i < This->baseShader.limits.texture; i++) {
shader_addline(buffer, "vec4 T%lu = gl_TexCoord[%lu];\n", i, i); shader_addline(buffer, "vec4 T%lu = gl_TexCoord[%lu];\n", i, i);
} }
/* Declare temporary variables */ /* Declare temporary variables */
for(i = 0; i < This->baseShader.limits.temporary; i++) { 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); shader_addline(buffer, "vec4 R%lu;\n", i);
} }
/* Declare all named attributes (TODO: Add this to the reg_maps /* Declare attributes */
* and only declare those that are needed) */
for (i = 0; i < This->baseShader.limits.attributes; i++) { 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 */ /* Temporary variables for matrix operations */
...@@ -765,13 +768,6 @@ void shader_generate_main( ...@@ -765,13 +768,6 @@ void shader_generate_main(
hw_arg.reg_maps = reg_maps; hw_arg.reg_maps = reg_maps;
This->baseShader.parse_state.current_row = 0; 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 */ /* Second pass, process opcodes */
if (NULL != pToken) { if (NULL != pToken) {
while (D3DPS_END() != *pToken) { while (D3DPS_END() != *pToken) {
......
...@@ -1333,6 +1333,9 @@ inline static VOID IWineD3DPixelShaderImpl_GenerateShader( ...@@ -1333,6 +1333,9 @@ inline static VOID IWineD3DPixelShaderImpl_GenerateShader(
/* Create the hw GLSL shader object and assign it as the baseShader.prgId */ /* Create the hw GLSL shader object and assign it as the baseShader.prgId */
GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB)); GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB));
/* Base Declarations */
shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, &reg_maps, &buffer);
/* Base Shader Body */ /* Base Shader Body */
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, &reg_maps, pFunction); shader_generate_main( (IWineD3DBaseShader*) This, &buffer, &reg_maps, pFunction);
...@@ -1362,6 +1365,9 @@ inline static VOID IWineD3DPixelShaderImpl_GenerateShader( ...@@ -1362,6 +1365,9 @@ inline static VOID IWineD3DPixelShaderImpl_GenerateShader(
shader_addline(&buffer, "PARAM coefmul = { 2, 4, 8, 16 };\n"); shader_addline(&buffer, "PARAM coefmul = { 2, 4, 8, 16 };\n");
shader_addline(&buffer, "PARAM one = { 1.0, 1.0, 1.0, 1.0 };\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 */ /* Base Shader Body */
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, &reg_maps, pFunction); shader_generate_main( (IWineD3DBaseShader*) This, &buffer, &reg_maps, pFunction);
......
...@@ -864,6 +864,9 @@ inline static VOID IWineD3DVertexShaderImpl_GenerateShader( ...@@ -864,6 +864,9 @@ inline static VOID IWineD3DVertexShaderImpl_GenerateShader(
/* Create the hw GLSL shader program and assign it as the baseShader.prgId */ /* Create the hw GLSL shader program and assign it as the baseShader.prgId */
GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB)); GLhandleARB shader_obj = GL_EXTCALL(glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB));
/* Base Declarations */
shader_generate_glsl_declarations( (IWineD3DBaseShader*) This, &reg_maps, &buffer);
/* Base Shader Body */ /* Base Shader Body */
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, &reg_maps, pFunction); shader_generate_main( (IWineD3DBaseShader*) This, &buffer, &reg_maps, pFunction);
...@@ -887,6 +890,9 @@ inline static VOID IWineD3DVertexShaderImpl_GenerateShader( ...@@ -887,6 +890,9 @@ inline static VOID IWineD3DVertexShaderImpl_GenerateShader(
This->baseShader.limits.constant_float = This->baseShader.limits.constant_float =
min(95, 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 */ /* Base Shader Body */
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, &reg_maps, pFunction); shader_generate_main( (IWineD3DBaseShader*) This, &buffer, &reg_maps, pFunction);
......
...@@ -1247,17 +1247,25 @@ struct glsl_shader_prog_link { ...@@ -1247,17 +1247,25 @@ struct glsl_shader_prog_link {
IWineD3DPixelShader* pixelShader; 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 { typedef struct shader_reg_maps {
DWORD texcoord;
DWORD temporary;
DWORD address;
/* Constants */ char texcoord[MAX_REG_TEXCRD]; /* pixel < 3.0 */
CHAR constantsF[256]; /* TODO: Make this dynamic */ 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 */ /* TODO: Integer and bool constants */
DWORD* semantics_in; DWORD* semantics_in; /* vertex, pixel */
DWORD* semantics_out; DWORD* semantics_out; /* vertex */
} shader_reg_maps; } shader_reg_maps;
...@@ -1372,6 +1380,16 @@ extern void shader_get_registers_used( ...@@ -1372,6 +1380,16 @@ extern void shader_get_registers_used(
shader_reg_maps* reg_maps, shader_reg_maps* reg_maps,
CONST DWORD* pToken); 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( extern void shader_generate_main(
IWineD3DBaseShader *iface, IWineD3DBaseShader *iface,
SHADER_BUFFER* buffer, 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