wined3d: Rework dcl processing.

The new function is called in pass 2 (getister counting/maps), and
it's now in baseshader. It operates on all INPUT and OUTPUT registers,
which, in addition to the old vertex shader input declarations covers
Shader Model 3.0 vshader output and pshader input declarations. The
result is stored into the reg_map structure.
This commit is contained in:
Ivan Gyurdiev 2006-06-12 02:53:32 -04:00 committed by Alexandre Julliard
parent f144d58ac2
commit 9bae7755ab
6 changed files with 224 additions and 158 deletions

View File

@ -172,10 +172,128 @@ unsigned int shader_get_float_offset(const DWORD reg) {
}
}
static void shader_parse_decl_usage(
DWORD *semantics_map,
DWORD usage_token, DWORD param) {
unsigned int usage = (usage_token & D3DSP_DCL_USAGE_MASK) >> D3DSP_DCL_USAGE_SHIFT;
unsigned int usage_idx = (usage_token & D3DSP_DCL_USAGEINDEX_MASK) >> D3DSP_DCL_USAGEINDEX_SHIFT;
unsigned int regnum = param & D3DSP_REGNUM_MASK;
switch(usage) {
case D3DDECLUSAGE_POSITION:
if (usage_idx == 0) { /* tween data */
TRACE("Setting position to %d\n", regnum);
semantics_map[WINED3DSHADERDECLUSAGE_POSITION] = param;
} else {
/* TODO: position indexes go from 0-8!!*/
TRACE("Setting position 2 to %d because usage_idx = %d\n", regnum, usage_idx);
/* robots uses positions up to 8, the position arrays are just packed.*/
if (usage_idx > 1) {
TRACE("Loaded for position %d (greater than 2)\n", usage_idx);
}
semantics_map[WINED3DSHADERDECLUSAGE_POSITION2 + usage_idx-1] = param;
}
break;
case D3DDECLUSAGE_BLENDINDICES:
TRACE("Setting BLENDINDICES to %d\n", regnum);
semantics_map[WINED3DSHADERDECLUSAGE_BLENDINDICES] = param;
if (usage_idx != 0) FIXME("Extended BLENDINDICES\n");
break;
case D3DDECLUSAGE_BLENDWEIGHT:
TRACE("Setting BLENDWEIGHT to %d\n", regnum);
semantics_map[WINED3DSHADERDECLUSAGE_BLENDWEIGHT] = param;
if (usage_idx != 0) FIXME("Extended blend weights\n");
break;
case D3DDECLUSAGE_NORMAL:
if (usage_idx == 0) { /* tween data */
TRACE("Setting normal to %d\n", regnum);
semantics_map[WINED3DSHADERDECLUSAGE_NORMAL] = param;
} else {
TRACE("Setting normal 2 to %d because usage = %d\n", regnum, usage_idx);
semantics_map[WINED3DSHADERDECLUSAGE_NORMAL2] = param;
}
break;
case D3DDECLUSAGE_PSIZE:
TRACE("Setting PSIZE to %d\n", regnum);
semantics_map[WINED3DSHADERDECLUSAGE_PSIZE] = param;
if (usage_idx != 0) FIXME("Extended PSIZE\n");
break;
case D3DDECLUSAGE_COLOR:
if (usage_idx == 0) {
TRACE("Setting DIFFUSE to %d\n", regnum);
semantics_map[WINED3DSHADERDECLUSAGE_DIFFUSE] = param;
} else {
TRACE("Setting SPECULAR to %d\n", regnum);
semantics_map[WINED3DSHADERDECLUSAGE_SPECULAR] = param;
}
break;
case D3DDECLUSAGE_TEXCOORD:
if (usage_idx > 7) {
FIXME("Program uses texture coordinate %d but only 0-7 have been "
"implemented\n", usage_idx);
} else {
TRACE("Setting TEXCOORD %d to %d\n", usage_idx, regnum);
semantics_map[WINED3DSHADERDECLUSAGE_TEXCOORD0 + usage_idx] = param;
}
break;
case D3DDECLUSAGE_TANGENT:
TRACE("Setting TANGENT to %d\n", regnum);
semantics_map[WINED3DSHADERDECLUSAGE_TANGENT] = param;
break;
case D3DDECLUSAGE_BINORMAL:
TRACE("Setting BINORMAL to %d\n", regnum);
semantics_map[WINED3DSHADERDECLUSAGE_BINORMAL] = param;
break;
case D3DDECLUSAGE_TESSFACTOR:
TRACE("Setting TESSFACTOR to %d\n", regnum);
semantics_map[WINED3DSHADERDECLUSAGE_TESSFACTOR] = param;
break;
case D3DDECLUSAGE_POSITIONT:
if (usage_idx == 0) { /* tween data */
FIXME("Setting positiont to %d\n", regnum);
semantics_map[WINED3DSHADERDECLUSAGE_POSITIONT] = param;
} else {
FIXME("Setting positiont 2 to %d because usage = %d\n", regnum, usage_idx);
semantics_map[WINED3DSHADERDECLUSAGE_POSITIONT2] = param;
if (usage_idx != 0) FIXME("Extended positiont\n");
}
break;
case D3DDECLUSAGE_FOG:
TRACE("Setting FOG to %d\n", regnum);
semantics_map[WINED3DSHADERDECLUSAGE_FOG] = param;
break;
case D3DDECLUSAGE_DEPTH:
TRACE("Setting DEPTH to %d\n", regnum);
semantics_map[WINED3DSHADERDECLUSAGE_DEPTH] = param;
break;
case D3DDECLUSAGE_SAMPLE:
TRACE("Setting SAMPLE to %d\n", regnum);
semantics_map[WINED3DSHADERDECLUSAGE_SAMPLE] = param;
break;
default:
FIXME("Unrecognised dcl %#x", usage);
}
}
/* Note that this does not count the loop register
* as an address register. */
static void shader_get_registers_used(
void shader_get_registers_used(
IWineD3DBaseShader *iface,
shader_reg_maps* reg_maps,
CONST DWORD* pToken) {
@ -216,10 +334,21 @@ static void shader_get_registers_used(
++pToken;
continue;
/* Skip declarations (for now) */
/* Handle declarations */
} else if (D3DSIO_DCL == curOpcode->opcode) {
pToken += curOpcode->num_params;
continue;
DWORD usage = *pToken++;
DWORD param = *pToken++;
DWORD regtype = shader_get_regtype(param);
if (D3DSPR_INPUT == regtype) {
shader_parse_decl_usage(reg_maps->semantics_in, usage, param);
} else if (D3DSPR_OUTPUT == regtype) {
shader_parse_decl_usage(reg_maps->semantics_out, usage, param);
}
/* Handle samplers here */
/* Skip definitions (for now) */
} else if (D3DSIO_DEF == curOpcode->opcode) {
@ -617,9 +746,10 @@ void generate_glsl_declarations(
that are specific to pixel or vertex functions
NOTE: A description of how to parse tokens can be found at:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/graphics/hh/graphics/usermodedisplaydriver_shader_cc8e4e05-f5c3-4ec0-8853-8ce07c1551b2.xml.asp */
void generate_base_shader(
void shader_generate_main(
IWineD3DBaseShader *iface,
SHADER_BUFFER* buffer,
shader_reg_maps* reg_maps,
CONST DWORD* pFunction) {
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) iface;
@ -628,30 +758,19 @@ void generate_base_shader(
SHADER_HANDLER hw_fct = NULL;
DWORD opcode_token;
DWORD i;
shader_reg_maps reg_maps;
SHADER_OPCODE_ARG hw_arg;
memset(&reg_maps, 0, sizeof(shader_reg_maps));
/* Initialize current parsing state */
hw_arg.shader = iface;
hw_arg.buffer = buffer;
hw_arg.reg_maps = &reg_maps;
hw_arg.reg_maps = reg_maps;
This->baseShader.parse_state.current_row = 0;
/* First pass: figure out which temporary and texture registers are used */
shader_get_registers_used(iface, &reg_maps, pToken);
/* TODO: check register usage against GL/Directx limits, and fail if they're exceeded
nUseAddressRegister < = GL_MAX_PROGRAM_ADDRESS_REGISTERS_AR
nUseTempRegister <= GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB
*/
/* Pre-declare registers */
if (wined3d_settings.shader_mode == SHADER_GLSL) {
generate_glsl_declarations(iface, &reg_maps, buffer);
generate_glsl_declarations(iface, reg_maps, buffer);
} else {
generate_arb_declarations(iface, &reg_maps, buffer);
generate_arb_declarations(iface, reg_maps, buffer);
}
/* Second pass, process opcodes */

View File

@ -833,33 +833,39 @@ static void draw_vertex(IWineD3DDevice *iface, /* interf
}
#endif /* TODO: Software shaders */
void loadNumberedArrays(IWineD3DDevice *iface, WineDirect3DVertexStridedData *sd, INT arrayUsageMap[WINED3DSHADERDECLUSAGE_MAX_USAGE]) {
void loadNumberedArrays(
IWineD3DDevice *iface,
WineDirect3DVertexStridedData *sd,
DWORD arrayUsageMap[WINED3DSHADERDECLUSAGE_MAX_USAGE]) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
#define LOAD_NUMBERED_ARRAY(_arrayName, _lookupName) \
if (sd->u.s._arrayName.lpData != NULL && ((arrayUsageMap[WINED3DSHADERDECLUSAGE_##_lookupName] & 0x7FFF) == arrayUsageMap[WINED3DSHADERDECLUSAGE_##_lookupName])) { \
TRACE_(d3d_shader)("Loading array %u with data from %s\n", arrayUsageMap[WINED3DSHADERDECLUSAGE_##_lookupName], #_arrayName); \
GL_EXTCALL(glVertexAttribPointerARB(arrayUsageMap[WINED3DSHADERDECLUSAGE_##_lookupName], \
if (sd->u.s._arrayName.lpData != NULL && arrayUsageMap[WINED3DSHADERDECLUSAGE_##_lookupName]) { \
unsigned int idx = arrayUsageMap[WINED3DSHADERDECLUSAGE_##_lookupName] & D3DSP_REGNUM_MASK; \
TRACE_(d3d_shader)("Loading array %u with data from %s\n", idx, #_arrayName); \
GL_EXTCALL(glVertexAttribPointerARB(idx, \
WINED3D_ATR_SIZE(_arrayName), \
WINED3D_ATR_GLTYPE(_arrayName), \
WINED3D_ATR_NORMALIZED(_arrayName), \
sd->u.s._arrayName.dwStride, \
sd->u.s._arrayName.lpData)); \
GL_EXTCALL(glEnableVertexAttribArrayARB(arrayUsageMap[WINED3DSHADERDECLUSAGE_##_lookupName])); \
GL_EXTCALL(glEnableVertexAttribArrayARB(idx)); \
}
#define LOAD_NUMBERED_POSITION_ARRAY(_lookupNumber) \
if (sd->u.s.position2.lpData != NULL && ((arrayUsageMap[WINED3DSHADERDECLUSAGE_POSITION2 + _lookupNumber] & 0x7FFF) == arrayUsageMap[WINED3DSHADERDECLUSAGE_POSITION2 + _lookupNumber])) { \
FIXME_(d3d_shader)("Loading array %u with data from %s\n", arrayUsageMap[WINED3DSHADERDECLUSAGE_POSITION2 + _lookupNumber], "position2"); \
GL_EXTCALL(glVertexAttribPointerARB(arrayUsageMap[WINED3DSHADERDECLUSAGE_POSITION2 + _lookupNumber], \
if (sd->u.s.position2.lpData != NULL && arrayUsageMap[WINED3DSHADERDECLUSAGE_POSITION2 + _lookupNumber]) { \
unsigned int idx = arrayUsageMap[WINED3DSHADERDECLUSAGE_POSITION2 + _lookupNumber] & D3DSP_REGNUM_MASK; \
TRACE_(d3d_shader)("Loading array %u with data from %s\n", idx, "position2"); \
GL_EXTCALL(glVertexAttribPointerARB(idx, \
WINED3D_ATR_SIZE(position2), \
WINED3D_ATR_GLTYPE(position2), \
WINED3D_ATR_NORMALIZED(position2), \
sd->u.s.position2.dwStride, \
((char *)sd->u.s.position2.lpData) + \
WINED3D_ATR_SIZE(position2) * WINED3D_ATR_TYPESIZE(position2) * _lookupNumber)); \
GL_EXTCALL(glEnableVertexAttribArrayARB(arrayUsageMap[WINED3DSHADERDECLUSAGE_POSITION2 + _lookupNumber])); \
GL_EXTCALL(glEnableVertexAttribArrayARB(idx)); \
}
/* Generate some lookup tables */

View File

@ -168,7 +168,9 @@ static void shader_glsl_get_register_name(
IWineD3DBaseShaderImpl* This = (IWineD3DBaseShaderImpl*) arg->shader;
BOOL pshader = shader_is_pshader_version(This->baseShader.hex_version);
char tmpStr[50];
*is_color = FALSE;
switch (regtype) {
case D3DSPR_TEMP:
sprintf(tmpStr, "R%lu", reg);
@ -182,10 +184,19 @@ static void shader_glsl_get_register_name(
}
} else {
IWineD3DVertexShaderImpl *vshader = (IWineD3DVertexShaderImpl*) arg->shader;
if (reg == vshader->arrayUsageMap[WINED3DSHADERDECLUSAGE_DIFFUSE]
|| reg == vshader->arrayUsageMap[WINED3DSHADERDECLUSAGE_SPECULAR]) {
(*is_color) = TRUE;
}
if (vshader->arrayUsageMap[WINED3DSHADERDECLUSAGE_DIFFUSE] &&
reg == (vshader->arrayUsageMap[WINED3DSHADERDECLUSAGE_DIFFUSE] & D3DSP_REGNUM_MASK))
*is_color = TRUE;
if (vshader->arrayUsageMap[WINED3DSHADERDECLUSAGE_SPECULAR] &&
reg == (vshader->arrayUsageMap[WINED3DSHADERDECLUSAGE_SPECULAR] & D3DSP_REGNUM_MASK))
*is_color = TRUE;
/* FIXME: Shaders in 8.1 appear to not require a dcl statement - use
* the reg value from the vertex declaration. However, arrayUsageMap is not initialized
* in that case - how can we know if an input contains color data or not? */
sprintf(tmpStr, "attrib%lu", reg);
}
break;

View File

@ -1305,6 +1305,17 @@ inline static VOID IWineD3DPixelShaderImpl_GenerateShader(
IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)iface;
SHADER_BUFFER buffer;
/* First pass: figure out which registers are used, what the semantics are, etc.. */
shader_reg_maps reg_maps;
DWORD semantics_in[WINED3DSHADERDECLUSAGE_MAX_USAGE];
memset(&reg_maps, 0, sizeof(shader_reg_maps));
memset(semantics_in, 0, WINED3DSHADERDECLUSAGE_MAX_USAGE * sizeof(DWORD));
reg_maps.semantics_in = semantics_in;
reg_maps.semantics_out = NULL;
shader_get_registers_used((IWineD3DBaseShader*) This, &reg_maps, pFunction);
/* FIXME: validate against OpenGL */
#if 0 /* FIXME: Use the buffer that is held by the device, this is ok since fixups will be skipped for software shaders
it also requires entering a critical section but cuts down the runtime footprint of wined3d and any memory fragmentation that may occur... */
if (This->device->fixupVertexBufferSize < SHADER_PGMSIZE) {
@ -1325,8 +1336,8 @@ 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));
/* Generate the bulk of the shader code */
generate_base_shader( (IWineD3DBaseShader*) This, &buffer, pFunction);
/* Base Shader Body */
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, &reg_maps, pFunction);
/* Pixel shaders < 2.0 place the resulting color in R0 implicitly */
if (This->baseShader.hex_version < D3DPS_VERSION(2,0))
@ -1354,9 +1365,8 @@ 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");
/** Call the base shader generation routine to generate most
of the pixel shader string for us */
generate_base_shader( (IWineD3DBaseShader*) This, &buffer, pFunction);
/* Base Shader Body */
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, &reg_maps, pFunction);
if (This->baseShader.hex_version < D3DPS_VERSION(2,0))
shader_addline(&buffer, "MOV result.color, R0;\n");

View File

@ -649,10 +649,19 @@ inline static void vshader_program_add_param(SHADER_OPCODE_ARG *arg, const DWORD
strcat(hwLine, tmpReg);
break;
case D3DSPR_INPUT:
if (reg == This->arrayUsageMap[WINED3DSHADERDECLUSAGE_DIFFUSE]
|| reg == This->arrayUsageMap[WINED3DSHADERDECLUSAGE_SPECULAR]) {
if (This->arrayUsageMap[WINED3DSHADERDECLUSAGE_DIFFUSE] &&
reg == (This->arrayUsageMap[WINED3DSHADERDECLUSAGE_DIFFUSE] & D3DSP_REGNUM_MASK))
is_color = TRUE;
}
if (This->arrayUsageMap[WINED3DSHADERDECLUSAGE_SPECULAR] &&
reg == (This->arrayUsageMap[WINED3DSHADERDECLUSAGE_SPECULAR] & D3DSP_REGNUM_MASK))
is_color = TRUE;
/* FIXME: Shaders in 8.1 appear to not require a dcl statement - use
* the reg value from the vertex declaration. However, arrayUsageMap is not initialized
* in that case - how can we know if an input contains color data or not? */
sprintf(tmpReg, "vertex.attrib[%lu]", reg);
strcat(hwLine, tmpReg);
break;
@ -700,109 +709,6 @@ inline static void vshader_program_add_param(SHADER_OPCODE_ARG *arg, const DWORD
}
}
static void vshader_parse_input_decl_usage(IWineD3DVertexShaderImpl *This, INT usage, INT arrayNo)
{
switch(usage & 0xFFFF) {
case D3DDECLUSAGE_POSITION:
if((usage & 0xF0000) >> 16 == 0) { /* tween data */
TRACE("Setting position to %d\n", arrayNo);
This->arrayUsageMap[WINED3DSHADERDECLUSAGE_POSITION] = arrayNo;
} else {
/* TODO: position indexes go from 0-8!!*/
TRACE("Setting position 2 to %d because usage = %d\n", arrayNo, (usage & 0xF0000) >> 16);
/* robots uses positions up to 8, the position arrays are just packed.*/
if ((usage & 0xF0000) >> 16 > 1) {
TRACE("Loaded for position %d (greater than 2)\n", (usage & 0xF0000) >> 16);
}
This->arrayUsageMap[WINED3DSHADERDECLUSAGE_POSITION2 + ((usage & 0xF0000) >> 16) -1] = arrayNo;
}
break;
case D3DDECLUSAGE_BLENDINDICES:
/* not supported by openGL */
TRACE("Setting BLENDINDICES to %d\n", arrayNo);
This->arrayUsageMap[WINED3DSHADERDECLUSAGE_BLENDINDICES] = arrayNo;
if ((usage & 0xF0000) >> 16 != 0) FIXME("Extended BLENDINDICES\n");
break;
case D3DDECLUSAGE_BLENDWEIGHT:
TRACE("Setting BLENDWEIGHT to %d\n", arrayNo);
This->arrayUsageMap[WINED3DSHADERDECLUSAGE_BLENDWEIGHT] = arrayNo;
if ((usage & 0xF0000) >> 16 != 0) FIXME("Extended blend weights\n");
break;
case D3DDECLUSAGE_NORMAL:
if((usage & 0xF0000) >> 16 == 0) { /* tween data */
TRACE("Setting normal to %d\n", arrayNo);
This->arrayUsageMap[WINED3DSHADERDECLUSAGE_NORMAL] = arrayNo;
} else {
TRACE("Setting normal 2 to %d because usage = %d\n", arrayNo, (usage & 0xF0000) >> 16);
This->arrayUsageMap[WINED3DSHADERDECLUSAGE_NORMAL2] = arrayNo;
}
break;
case D3DDECLUSAGE_PSIZE:
TRACE("Setting PSIZE to %d\n", arrayNo);
This->arrayUsageMap[WINED3DSHADERDECLUSAGE_PSIZE] = arrayNo;
if ((usage & 0xF0000) >> 16 != 0) FIXME("Extended PSIZE\n");
break;
case D3DDECLUSAGE_COLOR:
if((usage & 0xF0000) >> 16 == 0) {
TRACE("Setting DIFFUSE to %d\n", arrayNo);
This->arrayUsageMap[WINED3DSHADERDECLUSAGE_DIFFUSE] = arrayNo;
} else {
TRACE("Setting SPECULAR to %d\n", arrayNo);
This->arrayUsageMap[WINED3DSHADERDECLUSAGE_SPECULAR] = arrayNo;
}
break;
case D3DDECLUSAGE_TEXCOORD:
/* only 7 texture coords have been designed for, so run a quick sanity check */
if ((usage & 0xF0000) >> 16 > 7) {
FIXME("(%p) : Program uses texture coordinate %d but only 0-7 have been implemented\n", This, (usage & 0xF0000) >> 16);
} else {
TRACE("Setting TEXCOORD %d to %d\n", ((usage & 0xF0000) >> 16), arrayNo);
This->arrayUsageMap[WINED3DSHADERDECLUSAGE_TEXCOORD0 + ((usage & 0xF0000) >> 16)] = arrayNo;
}
break;
/* The following aren't supported by openGL,
if we get them then everything needs to be mapped to numbered attributes instead of named ones.
this should be caught in the first pass */
case D3DDECLUSAGE_TANGENT:
TRACE("Setting TANGENT to %d\n", arrayNo);
This->arrayUsageMap[WINED3DSHADERDECLUSAGE_TANGENT] = arrayNo;
break;
case D3DDECLUSAGE_BINORMAL:
TRACE("Setting BINORMAL to %d\n", arrayNo);
This->arrayUsageMap[WINED3DSHADERDECLUSAGE_BINORMAL] = arrayNo;
break;
case D3DDECLUSAGE_TESSFACTOR:
TRACE("Setting TESSFACTOR to %d\n", arrayNo);
This->arrayUsageMap[WINED3DSHADERDECLUSAGE_TESSFACTOR] = arrayNo;
break;
case D3DDECLUSAGE_POSITIONT:
if((usage & 0xF0000) >> 16 == 0) { /* tween data */
FIXME("Setting positiont to %d\n", arrayNo);
This->arrayUsageMap[WINED3DSHADERDECLUSAGE_POSITIONT] = arrayNo;
} else {
FIXME("Setting positiont 2 to %d because usage = %d\n", arrayNo, (usage & 0xF0000) >> 16);
This->arrayUsageMap[WINED3DSHADERDECLUSAGE_POSITIONT2] = arrayNo;
if ((usage & 0xF0000) >> 16 != 0) FIXME("Extended positiont\n");
}
break;
case D3DDECLUSAGE_FOG:
/* supported by OpenGL */
TRACE("Setting FOG to %d\n", arrayNo);
This->arrayUsageMap[WINED3DSHADERDECLUSAGE_FOG] = arrayNo;
break;
case D3DDECLUSAGE_DEPTH:
TRACE("Setting DEPTH to %d\n", arrayNo);
This->arrayUsageMap[WINED3DSHADERDECLUSAGE_DEPTH] = arrayNo;
break;
case D3DDECLUSAGE_SAMPLE:
TRACE("Setting SAMPLE to %d\n", arrayNo);
This->arrayUsageMap[WINED3DSHADERDECLUSAGE_SAMPLE] = arrayNo;
break;
default:
FIXME("Unrecognised dcl %08x", usage & 0xFFFF);
}
}
static void vshader_set_version(
IWineD3DVertexShaderImpl *This,
DWORD version) {
@ -931,6 +837,17 @@ inline static VOID IWineD3DVertexShaderImpl_GenerateShader(
IWineD3DVertexShaderImpl *This = (IWineD3DVertexShaderImpl *)iface;
SHADER_BUFFER buffer;
/* First pass: figure out which registers are used, what the semantics are, etc.. */
shader_reg_maps reg_maps;
DWORD semantics_out[WINED3DSHADERDECLUSAGE_MAX_USAGE];
memset(&reg_maps, 0, sizeof(shader_reg_maps));
memset(semantics_out, 0, WINED3DSHADERDECLUSAGE_MAX_USAGE * sizeof(DWORD));
reg_maps.semantics_in = This->arrayUsageMap;
reg_maps.semantics_out = semantics_out;
shader_get_registers_used((IWineD3DBaseShader*) This, &reg_maps, pFunction);
/* FIXME: validate against OpenGL */
#if 0 /* FIXME: Use the buffer that is held by the device, this is ok since fixups will be skipped for software shaders
it also requires entering a critical section but cuts down the runtime footprint of wined3d and any memory fragmentation that may occur... */
if (This->device->fixupVertexBufferSize < SHADER_PGMSIZE) {
@ -951,8 +868,8 @@ 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));
/* Generate the bulk of the shader code */
generate_base_shader( (IWineD3DBaseShader*) This, &buffer, pFunction);
/* Base Shader Body */
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, &reg_maps, pFunction);
shader_addline(&buffer, "}\n\0");
@ -974,9 +891,8 @@ inline static VOID IWineD3DVertexShaderImpl_GenerateShader(
This->baseShader.limits.constant_float =
min(95, This->baseShader.limits.constant_float);
/** Call the base shader generation routine to generate most
of the vertex shader string for us */
generate_base_shader( (IWineD3DBaseShader*) This, &buffer, pFunction);
/* Base Shader Body */
shader_generate_main( (IWineD3DBaseShader*) This, &buffer, &reg_maps, pFunction);
shader_addline(&buffer, "END\n\0");
@ -1408,10 +1324,6 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
DWORD i;
TRACE("(%p) : Parsing programme\n", This);
/* Initialise vertex input arrays */
for (i = 0; i < WINED3DSHADERDECLUSAGE_MAX_USAGE; i++)
This->arrayUsageMap[i] = -1;
if (NULL != pToken) {
while (D3DVS_END() != *pToken) {
if (shader_is_vshader_version(*pToken)) { /** version */
@ -1446,10 +1358,7 @@ static HRESULT WINAPI IWineD3DVertexShaderImpl_SetFunction(IWineD3DVertexShader
DWORD usage = *pToken;
DWORD param = *(pToken + 1);
DWORD regtype = shader_get_regtype(param);
if (regtype == D3DSPR_INPUT)
vshader_parse_input_decl_usage(This, usage, param & D3DSP_REGNUM_MASK);
shader_program_dump_decl_usage(usage, param);
shader_dump_ins_modifiers(param);
TRACE(" ");

View File

@ -1251,9 +1251,14 @@ typedef struct shader_reg_maps {
DWORD texcoord;
DWORD temporary;
DWORD address;
/* Constants */
CHAR constantsF[256]; /* TODO: Make this dynamic */
/* TODO: Integer and bool constants */
DWORD* semantics_in;
DWORD* semantics_out;
} shader_reg_maps;
#define SHADER_PGMSIZE 65535
@ -1367,9 +1372,15 @@ extern void shader_program_dump_decl_usage(
DWORD dcl,
DWORD param);
extern void generate_base_shader(
extern void shader_get_registers_used(
IWineD3DBaseShader *iface,
shader_reg_maps* reg_maps,
CONST DWORD* pToken);
extern void shader_generate_main(
IWineD3DBaseShader *iface,
SHADER_BUFFER* buffer,
shader_reg_maps* reg_maps,
CONST DWORD* pFunction);
extern void shader_dump_ins_modifiers(
@ -1432,7 +1443,7 @@ typedef struct IWineD3DVertexShaderImpl {
DWORD usage;
/* vertex declaration array mapping */
INT arrayUsageMap[WINED3DSHADERDECLUSAGE_MAX_USAGE];
DWORD arrayUsageMap[WINED3DSHADERDECLUSAGE_MAX_USAGE];
/* run time datas... */
VSHADERDATA *data;