wined3d: Clean up register use maps.
This commit is contained in:
parent
d59eeb3ee5
commit
cb973648ab
|
@ -30,6 +30,12 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d_shader);
|
||||||
|
|
||||||
#define GLNAME_REQUIRE_GLSL ((const char *)1)
|
#define GLNAME_REQUIRE_GLSL ((const char *)1)
|
||||||
|
|
||||||
|
typedef struct shader_reg_maps {
|
||||||
|
DWORD texcoord;
|
||||||
|
DWORD temporary;
|
||||||
|
DWORD address;
|
||||||
|
} shader_reg_maps;
|
||||||
|
|
||||||
inline static BOOL shader_is_version_token(DWORD token) {
|
inline static BOOL shader_is_version_token(DWORD token) {
|
||||||
return shader_is_pshader_version(token) ||
|
return shader_is_pshader_version(token) ||
|
||||||
shader_is_vshader_version(token);
|
shader_is_vshader_version(token);
|
||||||
|
@ -153,26 +159,22 @@ int shader_skip_unrecognized(
|
||||||
return tokens_read;
|
return tokens_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Note: For vertex shaders,
|
/* Note that this does not count the loop register
|
||||||
* texUsed = addrUsed, and
|
* as an address register. */
|
||||||
* D3DSPR_TEXTURE = D3DSPR_ADDR.
|
|
||||||
*
|
|
||||||
* Also note that this does not count the loop register
|
|
||||||
* as an address register. */
|
|
||||||
|
|
||||||
void shader_get_registers_used(
|
static void shader_get_registers_used(
|
||||||
IWineD3DBaseShader *iface,
|
IWineD3DBaseShader *iface,
|
||||||
|
shader_reg_maps* reg_maps,
|
||||||
CONST DWORD* pToken) {
|
CONST DWORD* pToken) {
|
||||||
|
|
||||||
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
|
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
|
||||||
DWORD* tempsUsed = &This->baseShader.temps_used;
|
|
||||||
DWORD* texUsed = &This->baseShader.textures_used;
|
|
||||||
|
|
||||||
if (pToken == NULL)
|
if (pToken == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
*tempsUsed = 0;
|
reg_maps->temporary = 0;
|
||||||
*texUsed = 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;
|
||||||
|
@ -233,10 +235,16 @@ void shader_get_registers_used(
|
||||||
regtype = (param & D3DSP_REGTYPE_MASK) >> D3DSP_REGTYPE_SHIFT;
|
regtype = (param & D3DSP_REGTYPE_MASK) >> D3DSP_REGTYPE_SHIFT;
|
||||||
reg = param & D3DSP_REGNUM_MASK;
|
reg = param & D3DSP_REGNUM_MASK;
|
||||||
|
|
||||||
if (D3DSPR_TEXTURE == regtype)
|
if (D3DSPR_TEXTURE == regtype) { /* vs: D3DSPR_ADDR */
|
||||||
*texUsed |= (1 << reg);
|
|
||||||
|
if (shader_is_pshader_version(This->baseShader.hex_version))
|
||||||
|
reg_maps->texcoord |= (1 << reg);
|
||||||
|
else
|
||||||
|
reg_maps->address |= (1 << reg);
|
||||||
|
}
|
||||||
|
|
||||||
if (D3DSPR_TEMP == regtype)
|
if (D3DSPR_TEMP == regtype)
|
||||||
*tempsUsed |= (1 << reg);
|
reg_maps->temporary |= (1 << reg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -498,30 +506,33 @@ 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 generate_arb_declarations(IWineD3DBaseShader *iface, SHADER_BUFFER* buffer) {
|
void generate_arb_declarations(
|
||||||
|
IWineD3DBaseShader *iface,
|
||||||
|
shader_reg_maps* reg_maps,
|
||||||
|
SHADER_BUFFER* buffer) {
|
||||||
|
|
||||||
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
|
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
|
||||||
DWORD i;
|
DWORD i;
|
||||||
|
|
||||||
for(i = 0; i < This->baseShader.limits.temporary; i++) {
|
for(i = 0; i < This->baseShader.limits.temporary; i++) {
|
||||||
if (This->baseShader.temps_used & (1 << i))
|
if (reg_maps->temporary & (1 << 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 (This->baseShader.textures_used & (1 << i))
|
if (reg_maps->address & (1 << 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 (This->baseShader.textures_used & (1 << i))
|
if (reg_maps->texcoord & (1 << 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 (This->baseShader.textures_used & (1 << i))
|
if (reg_maps->texcoord & (1 << 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Need to PARAM the environment parameters (constants) so we can use relative addressing */
|
/* Need to PARAM the environment parameters (constants) so we can use relative addressing */
|
||||||
|
@ -532,7 +543,10 @@ void generate_arb_declarations(IWineD3DBaseShader *iface, SHADER_BUFFER* buffer)
|
||||||
|
|
||||||
/** Generate the variable & register declarations for the GLSL
|
/** Generate the variable & register declarations for the GLSL
|
||||||
output target */
|
output target */
|
||||||
void generate_glsl_declarations(IWineD3DBaseShader *iface, SHADER_BUFFER* buffer) {
|
void generate_glsl_declarations(
|
||||||
|
IWineD3DBaseShader *iface,
|
||||||
|
shader_reg_maps* reg_maps,
|
||||||
|
SHADER_BUFFER* buffer) {
|
||||||
|
|
||||||
FIXME("GLSL not fully implemented yet.\n");
|
FIXME("GLSL not fully implemented yet.\n");
|
||||||
|
|
||||||
|
@ -554,14 +568,13 @@ void generate_base_shader(
|
||||||
SHADER_HANDLER hw_fct = NULL;
|
SHADER_HANDLER hw_fct = NULL;
|
||||||
DWORD opcode_token;
|
DWORD opcode_token;
|
||||||
DWORD i;
|
DWORD i;
|
||||||
|
shader_reg_maps reg_maps;
|
||||||
|
|
||||||
/* Initialize current parsing state */
|
/* Initialize current parsing state */
|
||||||
This->baseShader.parse_state.current_row = 0;
|
This->baseShader.parse_state.current_row = 0;
|
||||||
|
|
||||||
/* First pass: figure out which temporary and texture registers are used */
|
/* First pass: figure out which temporary and texture registers are used */
|
||||||
shader_get_registers_used(iface, pToken);
|
shader_get_registers_used(iface, ®_maps, pToken);
|
||||||
TRACE("Texture/Address registers used: %#lx, Temp registers used %#lx\n",
|
|
||||||
This->baseShader.textures_used, This->baseShader.temps_used);
|
|
||||||
|
|
||||||
/* TODO: check register usage against GL/Directx limits, and fail if they're exceeded
|
/* TODO: check register usage against GL/Directx limits, and fail if they're exceeded
|
||||||
nUseAddressRegister < = GL_MAX_PROGRAM_ADDRESS_REGISTERS_AR
|
nUseAddressRegister < = GL_MAX_PROGRAM_ADDRESS_REGISTERS_AR
|
||||||
|
@ -570,10 +583,10 @@ void generate_base_shader(
|
||||||
|
|
||||||
/* Pre-declare registers */
|
/* Pre-declare registers */
|
||||||
if (USING_GLSL) {
|
if (USING_GLSL) {
|
||||||
generate_glsl_declarations(iface, buffer);
|
generate_glsl_declarations(iface, ®_maps, buffer);
|
||||||
shader_addline(buffer, "void main() {\n");
|
shader_addline(buffer, "void main() {\n");
|
||||||
} else {
|
} else {
|
||||||
generate_arb_declarations(iface, buffer);
|
generate_arb_declarations(iface, ®_maps, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Second pass, process opcodes */
|
/* Second pass, process opcodes */
|
||||||
|
|
|
@ -1341,8 +1341,6 @@ typedef struct IWineD3DBaseShaderClass
|
||||||
{
|
{
|
||||||
DWORD version;
|
DWORD version;
|
||||||
DWORD hex_version;
|
DWORD hex_version;
|
||||||
DWORD temps_used;
|
|
||||||
DWORD textures_used;
|
|
||||||
SHADER_LIMITS limits;
|
SHADER_LIMITS limits;
|
||||||
SHADER_PARSE_STATE parse_state;
|
SHADER_PARSE_STATE parse_state;
|
||||||
CONST SHADER_OPCODE *shader_ins;
|
CONST SHADER_OPCODE *shader_ins;
|
||||||
|
@ -1360,10 +1358,6 @@ typedef struct IWineD3DBaseShaderImpl {
|
||||||
IWineD3DBaseShaderClass baseShader;
|
IWineD3DBaseShaderClass baseShader;
|
||||||
} IWineD3DBaseShaderImpl;
|
} IWineD3DBaseShaderImpl;
|
||||||
|
|
||||||
extern void shader_get_registers_used(
|
|
||||||
IWineD3DBaseShader *iface,
|
|
||||||
CONST DWORD* pToken);
|
|
||||||
|
|
||||||
extern void shader_program_dump_decl_usage(
|
extern void shader_program_dump_decl_usage(
|
||||||
DWORD dcl,
|
DWORD dcl,
|
||||||
DWORD param);
|
DWORD param);
|
||||||
|
|
Loading…
Reference in New Issue