diff --git a/dlls/wined3d/baseshader.c b/dlls/wined3d/baseshader.c index f62b71c15f3..21ec9442d3e 100644 --- a/dlls/wined3d/baseshader.c +++ b/dlls/wined3d/baseshader.c @@ -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(®_maps, 0, sizeof(shader_reg_maps)); - /* Initialize current parsing state */ hw_arg.shader = iface; hw_arg.buffer = buffer; - hw_arg.reg_maps = ®_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, ®_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, ®_maps, buffer); + generate_glsl_declarations(iface, reg_maps, buffer); } else { - generate_arb_declarations(iface, ®_maps, buffer); + generate_arb_declarations(iface, reg_maps, buffer); } /* Second pass, process opcodes */ diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c index 6c6e52640c1..acd708c8e0e 100644 --- a/dlls/wined3d/drawprim.c +++ b/dlls/wined3d/drawprim.c @@ -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 */ diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 92f6851e6f4..59a0b0589ba 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -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; diff --git a/dlls/wined3d/pixelshader.c b/dlls/wined3d/pixelshader.c index aaee6b1d6bc..455124ae8f8 100644 --- a/dlls/wined3d/pixelshader.c +++ b/dlls/wined3d/pixelshader.c @@ -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(®_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, ®_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, ®_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, ®_maps, pFunction); if (This->baseShader.hex_version < D3DPS_VERSION(2,0)) shader_addline(&buffer, "MOV result.color, R0;\n"); diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c index dd066c30dd1..17f364b219f 100644 --- a/dlls/wined3d/vertexshader.c +++ b/dlls/wined3d/vertexshader.c @@ -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(®_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, ®_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, ®_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, ®_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(" "); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 59b9692939a..a44e883d34f 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -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;