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;
 


Reply via email to