Use this updated patch. I forgot to initialize some constants to zero and made the diff against a wrong file because of which some crucial changes were missed.
Roderick > Hi, > > This patch adds most missing shader capabilities. Some capabilitise are > read from OpenGL but not everything is mappable to Direct3D in some cases an > extension from lets say Nvidia can be used but it is not really worth it. > If there's no OpenGL cap the minimum required values as required by the > shader specs are used. > > Regards, > Roderick Colenbrander -- "Feel free" – 10 GB Mailbox, 100 FreeSMS/Monat ... Jetzt GMX TopMail testen: http://www.gmx.net/de/go/topmail
--- dlls/wined3d/directx.c 2006-08-08 10:52:54.000000000 +0200 +++ dlls/wined3d/directx.c 2006-08-08 10:49:32.000000000 +0200 @@ -517,7 +517,11 @@ gl_info->max_samplers = 1; gl_info->max_sampler_stages = 1; gl_info->ps_arb_version = PS_VERSION_NOT_SUPPORTED; + gl_info->ps_arb_max_temps = 0; + gl_info->ps_arb_max_instructions = 0; gl_info->vs_arb_version = VS_VERSION_NOT_SUPPORTED; + gl_info->vs_arb_max_temps = 0; + gl_info->vs_arb_max_instructions = 0; gl_info->vs_nv_version = VS_VERSION_NOT_SUPPORTED; gl_info->vs_ati_version = VS_VERSION_NOT_SUPPORTED; gl_info->vs_glsl_constantsF = 0; @@ -579,6 +583,12 @@ GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max)); TRACE_(d3d_caps)(" FOUND: ARB Pixel Shader support - max float constants=%u\n", gl_max); gl_info->ps_arb_constantsF = gl_max; + GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_TEMPORARIES_ARB, &gl_max)); + TRACE_(d3d_caps)(" FOUND: ARB Pixel Shader support - max temporaries=%u\n", gl_max); + gl_info->ps_arb_max_temps = gl_max; + GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_INSTRUCTIONS_ARB, &gl_max)); + TRACE_(d3d_caps)(" FOUND: ARB Pixel Shader support - max instructions=%u\n", gl_max); + gl_info->ps_arb_max_instructions = gl_max; } else if (strcmp(ThisExtn, "GL_ARB_fragment_shader") == 0) { gl_info->supported[ARB_FRAGMENT_SHADER] = TRUE; glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, &gl_max); @@ -636,6 +646,12 @@ GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max)); TRACE_(d3d_caps)(" FOUND: ARB Vertex Shader support - max float constants=%u\n", gl_max); gl_info->vs_arb_constantsF = gl_max; + GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_TEMPORARIES_ARB, &gl_max)); + TRACE_(d3d_caps)(" FOUND: ARB Vertex Shader support - max temporaries=%u\n", gl_max); + gl_info->vs_arb_max_temps = gl_max; + GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_INSTRUCTIONS_ARB, &gl_max)); + TRACE_(d3d_caps)(" FOUND: ARB Vertex Shader support - max instructions=%u\n", gl_max); + gl_info->vs_arb_max_instructions = gl_max; } else if (strcmp(ThisExtn, "GL_ARB_vertex_shader") == 0) { gl_info->supported[ARB_VERTEX_SHADER] = TRUE; glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &gl_max); @@ -719,7 +735,7 @@ TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Fog Distance support\n"); gl_info->supported[NV_FOG_DISTANCE] = TRUE; } else if (strstr(ThisExtn, "GL_NV_fragment_program")) { - gl_info->ps_nv_version = PS_VERSION_11; + gl_info->ps_nv_version = (strcmp(ThisExtn, "GL_NV_fragment_program2") == 0) ? PS_VERSION_30 : PS_VERSION_20; TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Pixel Shader support - version=%02x\n", gl_info->ps_nv_version); } else if (strcmp(ThisExtn, "GL_NV_register_combiners") == 0) { glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &gl_max); @@ -748,8 +764,14 @@ TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Occlusion Query (3) support\n"); gl_info->supported[NV_OCCLUSION_QUERY] = TRUE; } else if (strstr(ThisExtn, "GL_NV_vertex_program")) { - gl_info->vs_nv_version = max(gl_info->vs_nv_version, (0 == strcmp(ThisExtn, "GL_NV_vertex_program1_1")) ? VS_VERSION_11 : VS_VERSION_10); - gl_info->vs_nv_version = max(gl_info->vs_nv_version, (0 == strcmp(ThisExtn, "GL_NV_vertex_program2")) ? VS_VERSION_20 : VS_VERSION_10); + if(strcmp(ThisExtn, "GL_NV_vertex_program3") == 0) + gl_info->vs_nv_version = VS_VERSION_30; + else if(strcmp(ThisExtn, "GL_NV_vertex_program2") == 0) + gl_info->vs_nv_version = VS_VERSION_20; + else if(strcmp(ThisExtn, "GL_NV_vertex_program1_1") == 0) + gl_info->vs_nv_version = VS_VERSION_11; + else + gl_info->vs_nv_version = VS_VERSION_10; TRACE_(d3d_caps)(" FOUND: NVIDIA (NV) Vertex Shader support - version=%02x\n", gl_info->vs_nv_version); gl_info->supported[NV_VERTEX_PROGRAM] = TRUE; @@ -2018,7 +2040,14 @@ /* FIXME: the shader mode should be per adapter */ if (wined3d_settings.vs_selected_mode == SHADER_GLSL) { - *pCaps->VertexShaderVersion = D3DVS_VERSION(3,0); + /* Nvidia Geforce6/7 or Ati R4xx/R5xx cards with GLSL support, support VS 3.0 but older Nvidia/Ati + models with GLSL support only support 2.0. In case of nvidia we can detect VS 2.0 support using + vs_nv_version which is based on NV_vertex_program. For Ati cards there's no easy way, so for + now only support 2.0/3.0 detection on Nvidia GeforceFX cards and default to 3.0 for everything else */ + if(This->gl_info.vs_nv_version == VS_VERSION_20) + *pCaps->VertexShaderVersion = D3DVS_VERSION(2,0); + else + *pCaps->VertexShaderVersion = D3DVS_VERSION(3,0); TRACE_(d3d_caps)("Hardware vertex shader version 3.0 enabled (GLSL)\n"); } else if (wined3d_settings.vs_selected_mode == SHADER_ARB) { *pCaps->VertexShaderVersion = D3DVS_VERSION(1,1); @@ -2033,9 +2062,14 @@ *pCaps->MaxVertexShaderConst = GL_LIMITS(vshader_constantsF); - /* FIXME: the shader ode should be per adapter */ + /* FIXME: the shader mode should be per adapter */ if (wined3d_settings.ps_selected_mode == SHADER_GLSL) { - *pCaps->PixelShaderVersion = D3DPS_VERSION(3,0); + /* See the comment about VS2.0/VS3.0 detection as we do the same here but then based on NV_fragment_program + in case of GeforceFX cards. */ + if(This->gl_info.ps_nv_version == PS_VERSION_20) + *pCaps->PixelShaderVersion = D3DPS_VERSION(2,0); + else + *pCaps->PixelShaderVersion = D3DPS_VERSION(3,0); /* FIXME: The following line is card dependent. -1.0 to 1.0 is a safe default clamp range for now */ *pCaps->PixelShader1xMaxValue = 1.0; TRACE_(d3d_caps)("Hardware pixel shader version 3.0 enabled (GLSL)\n"); @@ -2079,13 +2113,73 @@ #endif *pCaps->NumSimultaneousRTs = max_buffers; *pCaps->StretchRectFilterCaps = 0; - *pCaps->VS20Caps.Caps = 0; - *pCaps->PS20Caps.Caps = 0; *pCaps->VertexTextureFilterCaps = 0; - *pCaps->MaxVShaderInstructionsExecuted = 0; - *pCaps->MaxPShaderInstructionsExecuted = 0; - *pCaps->MaxVertexShader30InstructionSlots = 0; - *pCaps->MaxPixelShader30InstructionSlots = 0; + + if(*pCaps->VertexShaderVersion == D3DVS_VERSION(3,0)) { + /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering) + use the VS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum VS3.0 value. */ + *pCaps->VS20Caps.Caps = D3DVS20CAPS_PREDICATION; + *pCaps->VS20Caps.DynamicFlowControlDepth = D3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* VS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */ + *pCaps->VS20Caps.NumTemps = max(32, This->gl_info.vs_arb_max_temps); + *pCaps->VS20Caps.StaticFlowControlDepth = D3DVS20_MAX_STATICFLOWCONTROLDEPTH ; /* level of nesting in loops / if-statements; VS 3.0 requires MAX (4) */ + + *pCaps->MaxVShaderInstructionsExecuted = 65535; /* VS 3.0 needs atleast 65535, some cards even use 2^32-1 */ + *pCaps->MaxVertexShader30InstructionSlots = max(512, This->gl_info.vs_arb_max_instructions); + } else if(*pCaps->VertexShaderVersion == D3DVS_VERSION(2,0)) { + *pCaps->VS20Caps.Caps = 0; + *pCaps->VS20Caps.DynamicFlowControlDepth = D3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH; + *pCaps->VS20Caps.NumTemps = max(12, This->gl_info.vs_arb_max_temps); + *pCaps->VS20Caps.StaticFlowControlDepth = 1; + + *pCaps->MaxVShaderInstructionsExecuted = 65535; + *pCaps->MaxVertexShader30InstructionSlots = 0; + } else { /* VS 1.x */ + *pCaps->VS20Caps.Caps = 0; + *pCaps->VS20Caps.DynamicFlowControlDepth = 0; + *pCaps->VS20Caps.NumTemps = 0; + *pCaps->VS20Caps.StaticFlowControlDepth = 0; + + *pCaps->MaxVShaderInstructionsExecuted = 0; + *pCaps->MaxVertexShader30InstructionSlots = 0; + } + + if(*pCaps->PixelShaderVersion == D3DPS_VERSION(3,0)) { + /* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering) + use the PS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum PS 3.0 value. */ + + /* Caps is more or less undocumented on MSDN but it appears to be used for PS20Caps based on results from R9600/FX5900/Geforce6800 cards from Windows */ + *pCaps->PS20Caps.Caps = D3DPS20CAPS_ARBITRARYSWIZZLE | + D3DPS20CAPS_GRADIENTINSTRUCTIONS | + D3DPS20CAPS_PREDICATION | + D3DPS20CAPS_NODEPENDENTREADLIMIT | + D3DPS20CAPS_NOTEXINSTRUCTIONLIMIT; + *pCaps->PS20Caps.DynamicFlowControlDepth = D3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */ + *pCaps->PS20Caps.NumTemps = max(32, This->gl_info.ps_arb_max_temps); + *pCaps->PS20Caps.StaticFlowControlDepth = D3DPS20_MAX_STATICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_STATICFLOWCONTROLDEPTH (4) */ + *pCaps->PS20Caps.NumInstructionSlots = D3DPS20_MAX_NUMINSTRUCTIONSLOTS; /* PS 3.0 requires MAX_NUMINSTRUCTIONSLOTS (512) */ + + *pCaps->MaxPShaderInstructionsExecuted = 65535; + *pCaps->MaxPixelShader30InstructionSlots = max(D3DMIN30SHADERINSTRUCTIONS, This->gl_info.ps_arb_max_instructions); + } else if(*pCaps->PixelShaderVersion == D3DPS_VERSION(2,0)) { + /* Below we assume PS2.0 specs, not extended 2.0a(GeforceFX)/2.0b(Radeon R3xx) ones */ + *pCaps->PS20Caps.Caps = 0; + *pCaps->PS20Caps.DynamicFlowControlDepth = 0; /* D3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH = 0 */ + *pCaps->PS20Caps.NumTemps = max(12, This->gl_info.ps_arb_max_temps); + *pCaps->PS20Caps.StaticFlowControlDepth = D3DPS20_MIN_STATICFLOWCONTROLDEPTH; /* Minumum: 1 */ + *pCaps->PS20Caps.NumInstructionSlots = D3DPS20_MIN_NUMINSTRUCTIONSLOTS; /* Minimum number (64 ALU + 32 Texture), a GeforceFX uses 512 */ + + *pCaps->MaxPShaderInstructionsExecuted = 512; /* Minimum value, a GeforceFX uses 1024 */ + *pCaps->MaxPixelShader30InstructionSlots = 0; + } else { /* PS 1.x */ + *pCaps->PS20Caps.Caps = 0; + *pCaps->PS20Caps.DynamicFlowControlDepth = 0; + *pCaps->PS20Caps.NumTemps = 0; + *pCaps->PS20Caps.StaticFlowControlDepth = 0; + *pCaps->PS20Caps.NumInstructionSlots = 0; + + *pCaps->MaxPShaderInstructionsExecuted = 0; + *pCaps->MaxPixelShader30InstructionSlots = 0; + } } return WINED3D_OK; --- include/wine/wined3d_gl.h 2006-08-08 10:51:23.000000000 +0200 +++ include/wine/wined3d_gl.h 2006-08-07 22:44:16.000000000 +0200 @@ -1713,7 +1712,11 @@ unsigned max_pshader_constantsF; unsigned vs_arb_constantsF; + unsigned vs_arb_max_instructions; + unsigned vs_arb_max_temps; unsigned ps_arb_constantsF; + unsigned ps_arb_max_instructions; + unsigned ps_arb_max_temps; unsigned vs_glsl_constantsF; unsigned ps_glsl_constantsF;