From 3d112b6525af5b95fb357221d8c051c88e82eb61 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Sun, 24 Jan 2010 21:16:14 +0100 Subject: [PATCH] wined3d: Add support for EXT_gpu_shader4 provided sampling functions with explicit derivatives. --- dlls/wined3d/glsl_shader.c | 131 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 101 insertions(+), 30 deletions(-) diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 1196387170a..0ab3c2c34cb 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, -- 2.11.4.GIT