[PATCH 5/5] wined3d: Add support for EXT_gpu_shader4 provided sampling functions with explicit derivatives.

Henri Verbeet hverbeet at codeweavers.com
Sun Jan 24 14:16:14 CST 2010


---
 dlls/wined3d/glsl_shader.c |  131 ++++++++++++++++++++++++++++++++++----------
 1 files changed, 101 insertions(+), 30 deletions(-)

diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 1196387..0ab3c2c 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -1551,7 +1551,8 @@ static inline const char *shader_get_comp_op(DWORD op)
     }
 }
 
-static void shader_glsl_get_sample_function(DWORD sampler_type, DWORD flags, glsl_sample_function_t *sample_function)
+static void shader_glsl_get_sample_function(const struct wined3d_gl_info *gl_info,
+        DWORD sampler_type, DWORD flags, glsl_sample_function_t *sample_function)
 {
     BOOL projected = flags & WINED3D_GLSL_SAMPLE_PROJECTED;
     BOOL texrect = flags & WINED3D_GLSL_SAMPLE_RECT;
@@ -1563,9 +1564,21 @@ static void shader_glsl_get_sample_function(DWORD sampler_type, DWORD flags, gls
         case WINED3DSTT_1D:
             if(lod) {
                 sample_function->name = projected ? "texture1DProjLod" : "texture1DLod";
-            } else  if(grad) {
-                sample_function->name = projected ? "texture1DProjGradARB" : "texture1DGradARB";
-            } else {
+            }
+            else  if (grad)
+            {
+                if (gl_info->supported[EXT_GPU_SHADER4])
+                    sample_function->name = projected ? "texture1DProjGrad" : "texture1DGrad";
+                else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
+                    sample_function->name = projected ? "texture1DProjGradARB" : "texture1DGradARB";
+                else
+                {
+                    FIXME("Unsupported 1D grad function.\n");
+                    sample_function->name = "unsupported1DGrad";
+                }
+            }
+            else
+            {
                 sample_function->name = projected ? "texture1DProj" : "texture1D";
             }
             sample_function->coord_mask = WINED3DSP_WRITEMASK_0;
@@ -1574,17 +1587,41 @@ static void shader_glsl_get_sample_function(DWORD sampler_type, DWORD flags, gls
             if(texrect) {
                 if(lod) {
                     sample_function->name = projected ? "texture2DRectProjLod" : "texture2DRectLod";
-                } else  if(grad) {
-                    sample_function->name = projected ? "texture2DRectProjGradARB" : "texture2DRectGradARB";
-                } else {
+                }
+                else  if (grad)
+                {
+                    if (gl_info->supported[EXT_GPU_SHADER4])
+                        sample_function->name = projected ? "texture2DRectProjGrad" : "texture2DRectGrad";
+                    else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
+                        sample_function->name = projected ? "texture2DRectProjGradARB" : "texture2DRectGradARB";
+                    else
+                    {
+                        FIXME("Unsupported RECT grad function.\n");
+                        sample_function->name = "unsupported2DRectGrad";
+                    }
+                }
+                else
+                {
                     sample_function->name = projected ? "texture2DRectProj" : "texture2DRect";
                 }
             } else {
                 if(lod) {
                     sample_function->name = projected ? "texture2DProjLod" : "texture2DLod";
-                } else  if(grad) {
-                    sample_function->name = projected ? "texture2DProjGradARB" : "texture2DGradARB";
-                } else {
+                }
+                else  if (grad)
+                {
+                    if (gl_info->supported[EXT_GPU_SHADER4])
+                        sample_function->name = projected ? "texture2DProjGrad" : "texture2DGrad";
+                    else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
+                        sample_function->name = projected ? "texture2DProjGradARB" : "texture2DGradARB";
+                    else
+                    {
+                        FIXME("Unsupported 2D grad function.\n");
+                        sample_function->name = "unsupported2DGrad";
+                    }
+                }
+                else
+                {
                     sample_function->name = projected ? "texture2DProj" : "texture2D";
                 }
             }
@@ -1593,9 +1630,21 @@ static void shader_glsl_get_sample_function(DWORD sampler_type, DWORD flags, gls
         case WINED3DSTT_CUBE:
             if(lod) {
                 sample_function->name = "textureCubeLod";
-            } else if(grad) {
-                sample_function->name = "textureCubeGradARB";
-            } else {
+            }
+            else if (grad)
+            {
+                if (gl_info->supported[EXT_GPU_SHADER4])
+                    sample_function->name = "textureCubeGrad";
+                else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
+                    sample_function->name = "textureCubeGradARB";
+                else
+                {
+                    FIXME("Unsupported Cube grad function.\n");
+                    sample_function->name = "unsupportedCubeGrad";
+                }
+            }
+            else
+            {
                 sample_function->name = "textureCube";
             }
             sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
@@ -1603,9 +1652,21 @@ static void shader_glsl_get_sample_function(DWORD sampler_type, DWORD flags, gls
         case WINED3DSTT_VOLUME:
             if(lod) {
                 sample_function->name = projected ? "texture3DProjLod" : "texture3DLod";
-            } else  if(grad) {
-                sample_function->name = projected ? "texture3DProjGradARB" : "texture3DGradARB";
-            } else {
+            }
+            else  if (grad)
+            {
+                if (gl_info->supported[EXT_GPU_SHADER4])
+                    sample_function->name = projected ? "texture3DProjGrad" : "texture3DGrad";
+                else if (gl_info->supported[ARB_SHADER_TEXTURE_LOD])
+                    sample_function->name = projected ? "texture3DProjGradARB" : "texture3DGradARB";
+                else
+                {
+                    FIXME("Unsupported 3D grad function.\n");
+                    sample_function->name = "unsupported3DGrad";
+                }
+            }
+            else
+            {
                 sample_function->name = projected ? "texture3DProj" : "texture3D";
             }
             sample_function->coord_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
@@ -2686,6 +2747,7 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins)
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
     DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
             ins->ctx->reg_maps->shader_version.minor);
+    const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
     glsl_sample_function_t sample_function;
     DWORD sample_flags = 0;
     WINED3DSAMPLER_TEXTURE_TYPE sampler_type;
@@ -2739,7 +2801,7 @@ static void shader_glsl_tex(const struct wined3d_shader_instruction *ins)
         sample_flags |= WINED3D_GLSL_SAMPLE_RECT;
     }
 
-    shader_glsl_get_sample_function(sampler_type, sample_flags, &sample_function);
+    shader_glsl_get_sample_function(gl_info, sampler_type, sample_flags, &sample_function);
     mask |= sample_function.coord_mask;
 
     if (shader_version < WINED3D_SHADER_VERSION(2,0)) swizzle = WINED3DSP_NOSWIZZLE;
@@ -2781,7 +2843,7 @@ static void shader_glsl_texldd(const struct wined3d_shader_instruction *ins)
     DWORD sampler_idx;
     DWORD swizzle = ins->src[1].swizzle;
 
-    if (!gl_info->supported[ARB_SHADER_TEXTURE_LOD])
+    if (!gl_info->supported[ARB_SHADER_TEXTURE_LOD] && !gl_info->supported[EXT_GPU_SHADER4])
     {
         FIXME("texldd used, but not supported by hardware. Falling back to regular tex\n");
         return shader_glsl_tex(ins);
@@ -2794,7 +2856,7 @@ static void shader_glsl_texldd(const struct wined3d_shader_instruction *ins)
         sample_flags |= WINED3D_GLSL_SAMPLE_RECT;
     }
 
-    shader_glsl_get_sample_function(sampler_type, sample_flags, &sample_function);
+    shader_glsl_get_sample_function(gl_info, sampler_type, sample_flags, &sample_function);
     shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param);
     shader_glsl_add_src_param(ins, &ins->src[2], sample_function.coord_mask, &dx_param);
     shader_glsl_add_src_param(ins, &ins->src[3], sample_function.coord_mask, &dy_param);
@@ -2821,12 +2883,12 @@ static void shader_glsl_texldl(const struct wined3d_shader_instruction *ins)
        IWineD3DBaseTexture_GetTextureDimensions(deviceImpl->stateBlock->textures[sampler_idx]) == GL_TEXTURE_RECTANGLE_ARB) {
         sample_flags |= WINED3D_GLSL_SAMPLE_RECT;
     }
-    shader_glsl_get_sample_function(sampler_type, sample_flags, &sample_function);
+    shader_glsl_get_sample_function(gl_info, sampler_type, sample_flags, &sample_function);
     shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &coord_param);
 
     shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_3, &lod_param);
 
-    if (!gl_info->supported[ARB_SHADER_TEXTURE_LOD]
+    if (!gl_info->supported[ARB_SHADER_TEXTURE_LOD] && !gl_info->supported[EXT_GPU_SHADER4]
             && shader_is_pshader_version(ins->ctx->reg_maps->shader_version.type))
     {
         /* The GLSL spec claims the Lod sampling functions are only supported in vertex shaders.
@@ -2888,6 +2950,7 @@ static void shader_glsl_texcoord(const struct wined3d_shader_instruction *ins)
  * then perform a 1D texture lookup from stage dstregnum, place into dst. */
 static void shader_glsl_texdp3tex(const struct wined3d_shader_instruction *ins)
 {
+    const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
     glsl_src_param_t src0_param;
     glsl_sample_function_t sample_function;
     DWORD sampler_idx = ins->dst[0].reg.idx;
@@ -2902,7 +2965,7 @@ static void shader_glsl_texdp3tex(const struct wined3d_shader_instruction *ins)
      *
      * It is a dependent read - not valid with conditional NP2 textures
      */
-    shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
+    shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function);
     mask_size = shader_glsl_get_write_mask_size(sample_function.coord_mask);
 
     switch(mask_size)
@@ -3015,6 +3078,7 @@ static void shader_glsl_texm3x3pad(const struct wined3d_shader_instruction *ins)
 
 static void shader_glsl_texm3x2tex(const struct wined3d_shader_instruction *ins)
 {
+    const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
     DWORD reg = ins->dst[0].reg.idx;
     struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
@@ -3025,7 +3089,7 @@ static void shader_glsl_texm3x2tex(const struct wined3d_shader_instruction *ins)
     shader_glsl_add_src_param(ins, &ins->src[0], src_mask, &src0_param);
     shader_addline(buffer, "tmp0.y = dot(T%u.xyz, %s);\n", reg, src0_param.param_str);
 
-    shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
+    shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function);
 
     /* Sample the texture using the calculated coordinates */
     shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xy");
@@ -3036,6 +3100,7 @@ static void shader_glsl_texm3x2tex(const struct wined3d_shader_instruction *ins)
 static void shader_glsl_texm3x3tex(const struct wined3d_shader_instruction *ins)
 {
     DWORD src_mask = WINED3DSP_WRITEMASK_0 | WINED3DSP_WRITEMASK_1 | WINED3DSP_WRITEMASK_2;
+    const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
     glsl_src_param_t src0_param;
     DWORD reg = ins->dst[0].reg.idx;
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
@@ -3047,7 +3112,7 @@ static void shader_glsl_texm3x3tex(const struct wined3d_shader_instruction *ins)
     shader_addline(ins->ctx->buffer, "tmp0.z = dot(T%u.xyz, %s);\n", reg, src0_param.param_str);
 
     /* Dependent read, not valid with conditional NP2 */
-    shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
+    shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function);
 
     /* Sample the texture using the calculated coordinates */
     shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz");
@@ -3080,6 +3145,7 @@ static void shader_glsl_texm3x3(const struct wined3d_shader_instruction *ins)
 static void shader_glsl_texm3x3spec(const struct wined3d_shader_instruction *ins)
 {
     IWineD3DPixelShaderImpl *shader = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
+    const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
     DWORD reg = ins->dst[0].reg.idx;
     glsl_src_param_t src0_param;
     glsl_src_param_t src1_param;
@@ -3098,7 +3164,7 @@ static void shader_glsl_texm3x3spec(const struct wined3d_shader_instruction *ins
     shader_addline(buffer, "tmp0.xyz = -reflect((%s), normalize(tmp0.xyz));\n", src1_param.param_str);
 
     /* Dependent read, not valid with conditional NP2 */
-    shader_glsl_get_sample_function(stype, 0, &sample_function);
+    shader_glsl_get_sample_function(gl_info, stype, 0, &sample_function);
 
     /* Sample the texture */
     shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz");
@@ -3111,6 +3177,7 @@ static void shader_glsl_texm3x3spec(const struct wined3d_shader_instruction *ins
 static void shader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *ins)
 {
     IWineD3DPixelShaderImpl *shader = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
+    const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
     DWORD reg = ins->dst[0].reg.idx;
     struct wined3d_shader_buffer *buffer = ins->ctx->buffer;
     SHADER_PARSE_STATE* current_state = &shader->baseShader.parse_state;
@@ -3130,7 +3197,7 @@ static void shader_glsl_texm3x3vspec(const struct wined3d_shader_instruction *in
     shader_addline(buffer, "tmp0.xyz = -reflect(tmp1.xyz, normalize(tmp0.xyz));\n");
 
     /* Dependent read, not valid with conditional NP2 */
-    shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
+    shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function);
 
     /* Sample the texture using the calculated coordinates */
     shader_glsl_gen_sample_code(ins, reg, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL, "tmp0.xyz");
@@ -3146,6 +3213,7 @@ static void shader_glsl_texbem(const struct wined3d_shader_instruction *ins)
 {
     IWineD3DPixelShaderImpl *This = (IWineD3DPixelShaderImpl *)ins->ctx->shader;
     IWineD3DDeviceImpl* deviceImpl = (IWineD3DDeviceImpl*) This->baseShader.device;
+    const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
     glsl_sample_function_t sample_function;
     glsl_src_param_t coord_param;
     WINED3DSAMPLER_TEXTURE_TYPE sampler_type;
@@ -3159,7 +3227,7 @@ static void shader_glsl_texbem(const struct wined3d_shader_instruction *ins)
 
     sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
     /* Dependent read, not valid with conditional NP2 */
-    shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
+    shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function);
     mask = sample_function.coord_mask;
 
     shader_glsl_write_mask_to_str(mask, coord_mask);
@@ -3218,6 +3286,7 @@ static void shader_glsl_bem(const struct wined3d_shader_instruction *ins)
  * Sample 2D texture at dst using the alpha & red (wx) components of src as texture coordinates */
 static void shader_glsl_texreg2ar(const struct wined3d_shader_instruction *ins)
 {
+    const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
     glsl_src_param_t src0_param;
     DWORD sampler_idx = ins->dst[0].reg.idx;
     WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
@@ -3225,7 +3294,7 @@ static void shader_glsl_texreg2ar(const struct wined3d_shader_instruction *ins)
 
     shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param);
 
-    shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
+    shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function);
     shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
             "%s.wx", src0_param.reg_name);
 }
@@ -3234,6 +3303,7 @@ static void shader_glsl_texreg2ar(const struct wined3d_shader_instruction *ins)
  * Sample 2D texture at dst using the green & blue (yz) components of src as texture coordinates */
 static void shader_glsl_texreg2gb(const struct wined3d_shader_instruction *ins)
 {
+    const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
     glsl_src_param_t src0_param;
     DWORD sampler_idx = ins->dst[0].reg.idx;
     WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
@@ -3241,7 +3311,7 @@ static void shader_glsl_texreg2gb(const struct wined3d_shader_instruction *ins)
 
     shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param);
 
-    shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
+    shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function);
     shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
             "%s.yz", src0_param.reg_name);
 }
@@ -3250,13 +3320,14 @@ static void shader_glsl_texreg2gb(const struct wined3d_shader_instruction *ins)
  * Sample texture at dst using the rgb (xyz) components of src as texture coordinates */
 static void shader_glsl_texreg2rgb(const struct wined3d_shader_instruction *ins)
 {
+    const struct wined3d_gl_info *gl_info = ins->ctx->gl_info;
     glsl_src_param_t src0_param;
     DWORD sampler_idx = ins->dst[0].reg.idx;
     WINED3DSAMPLER_TEXTURE_TYPE sampler_type = ins->ctx->reg_maps->sampler_type[sampler_idx];
     glsl_sample_function_t sample_function;
 
     /* Dependent read, not valid with conditional NP2 */
-    shader_glsl_get_sample_function(sampler_type, 0, &sample_function);
+    shader_glsl_get_sample_function(gl_info, sampler_type, 0, &sample_function);
     shader_glsl_add_src_param(ins, &ins->src[0], sample_function.coord_mask, &src0_param);
 
     shader_glsl_gen_sample_code(ins, sampler_idx, &sample_function, WINED3DSP_NOSWIZZLE, NULL, NULL, NULL,
-- 
1.6.4.4




More information about the wine-patches mailing list