From: Matteo Bruni mbruni@codeweavers.com
--- dlls/wined3d/adapter_gl.c | 1 + dlls/wined3d/arb_program_shader.c | 34 ++++++++++++++++++++++++++----- dlls/wined3d/glsl_shader.c | 15 ++------------ dlls/wined3d/wined3d_gl.h | 1 + dlls/wined3d/wined3d_private.h | 11 ++++++++++ 5 files changed, 44 insertions(+), 18 deletions(-)
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c index c3925b7c3d0..bd7bd3a1222 100644 --- a/dlls/wined3d/adapter_gl.c +++ b/dlls/wined3d/adapter_gl.c @@ -84,6 +84,7 @@ static const struct wined3d_extension_map gl_extension_map[] = {"GL_ARB_fragment_coord_conventions", ARB_FRAGMENT_COORD_CONVENTIONS}, {"GL_ARB_fragment_layer_viewport", ARB_FRAGMENT_LAYER_VIEWPORT }, {"GL_ARB_fragment_program", ARB_FRAGMENT_PROGRAM }, + {"GL_ARB_fragment_program_shadow", ARB_FRAGMENT_PROGRAM_SHADOW }, {"GL_ARB_fragment_shader", ARB_FRAGMENT_SHADER }, {"GL_ARB_framebuffer_no_attachments", ARB_FRAMEBUFFER_NO_ATTACHMENTS}, {"GL_ARB_framebuffer_object", ARB_FRAMEBUFFER_OBJECT }, diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index c2eeadfdcbe..806fae6b522 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -1426,6 +1426,7 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, unsig enum wined3d_shader_resource_type resource_type; struct color_fixup_masks masks; const char *tex_dst = dst_str; + bool shadow_sampler, tex_rect; BOOL np2_fixup = FALSE; const char *tex_type; const char *mod; @@ -1443,18 +1444,35 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, unsig sampler_idx += WINED3D_MAX_FRAGMENT_SAMPLERS; }
+ shadow_sampler = priv->gl_info->supported[ARB_FRAGMENT_PROGRAM_SHADOW] + && shader_sampler_is_shadow(ins->ctx->shader, &priv->cur_ps_args->super, sampler_idx, sampler_idx); + switch (resource_type) { case WINED3D_SHADER_RESOURCE_TEXTURE_1D: - tex_type = "1D"; + if (shadow_sampler) + tex_type = "SHADOW1D"; + else + tex_type = "1D"; break;
case WINED3D_SHADER_RESOURCE_TEXTURE_2D: - if (pshader && priv->cur_ps_args->super.np2_fixup & (1u << sampler_idx) - && priv->gl_info->supported[ARB_TEXTURE_RECTANGLE]) - tex_type = "RECT"; + tex_rect = pshader && priv->cur_ps_args->super.np2_fixup & (1u << sampler_idx) + && priv->gl_info->supported[ARB_TEXTURE_RECTANGLE]; + if (shadow_sampler) + { + if (tex_rect) + tex_type = "SHADOWRECT"; + else + tex_type = "SHADOW2D"; + } else - tex_type = "2D"; + { + if (tex_rect) + tex_type = "RECT"; + else + tex_type = "2D"; + }
if (pshader) { @@ -1467,10 +1485,14 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, unsig break;
case WINED3D_SHADER_RESOURCE_TEXTURE_3D: + if (shadow_sampler) + FIXME("Unsupported 3D shadow sampler.\n"); tex_type = "3D"; break;
case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE: + if (shadow_sampler) + FIXME("Unsupported cube shadow sampler.\n"); tex_type = "CUBE"; break;
@@ -3656,6 +3678,8 @@ static GLuint shader_arb_generate_pshader(const struct wined3d_shader *shader, break; } } + if (gl_info->supported[ARB_FRAGMENT_PROGRAM_SHADOW]) + shader_addline(buffer, "OPTION ARB_fragment_program_shadow;\n");
/* For now always declare the temps. At least the Nvidia assembler optimizes completely * unused temps away(but occupies them for the whole shader if they're used once). Always diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index e381e8df7a4..9ab3f722d31 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -2110,17 +2110,6 @@ static BOOL glsl_is_color_reg_read(const struct wined3d_shader *shader, unsigned return FALSE; }
-static BOOL glsl_is_shadow_sampler(const struct wined3d_shader *shader, - const struct ps_compile_args *ps_args, unsigned int resource_idx, unsigned int sampler_idx) -{ - const struct wined3d_shader_version *version = &shader->reg_maps.shader_version; - - if (version->major >= 4) - return shader->reg_maps.sampler_comparison_mode & (1u << sampler_idx); - else - return version->type == WINED3D_SHADER_TYPE_PIXEL && (ps_args->shadow & (1u << resource_idx)); -} - static void shader_glsl_declare_typed_vertex_attribute(struct wined3d_string_buffer *buffer, const struct wined3d_gl_info *gl_info, const char *vector_type, const char *scalar_type, unsigned int index) @@ -2345,7 +2334,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context_gl *c break; }
- shadow_sampler = glsl_is_shadow_sampler(shader, ps_args, entry->resource_idx, entry->sampler_idx); + shadow_sampler = shader_sampler_is_shadow(shader, ps_args, entry->resource_idx, entry->sampler_idx); resource_type = version->type == WINED3D_SHADER_TYPE_PIXEL ? pixelshader_get_resource_type(reg_maps, entry->resource_idx, ps_args->tex_types) : reg_maps->resource_info[entry->resource_idx].type; @@ -3424,7 +3413,7 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context enum wined3d_shader_resource_type resource_type; struct shader_glsl_ctx_priv *priv = ctx->backend_data; const struct wined3d_gl_info *gl_info = priv->gl_info; - BOOL shadow = glsl_is_shadow_sampler(ctx->shader, priv->cur_ps_args, resource_idx, sampler_idx); + BOOL shadow = shader_sampler_is_shadow(ctx->shader, priv->cur_ps_args, resource_idx, sampler_idx); BOOL projected = flags & WINED3D_GLSL_SAMPLE_PROJECTED; BOOL texrect = ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL && priv->cur_ps_args->np2_fixup & (1u << resource_idx) diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h index ceb534a10a4..f5cec2ccdd7 100644 --- a/dlls/wined3d/wined3d_gl.h +++ b/dlls/wined3d/wined3d_gl.h @@ -78,6 +78,7 @@ enum wined3d_gl_extension ARB_FRAGMENT_COORD_CONVENTIONS, ARB_FRAGMENT_LAYER_VIEWPORT, ARB_FRAGMENT_PROGRAM, + ARB_FRAGMENT_PROGRAM_SHADOW, ARB_FRAGMENT_SHADER, ARB_FRAMEBUFFER_NO_ATTACHMENTS, ARB_FRAMEBUFFER_OBJECT, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 4506186229a..e0841ed7595 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4384,6 +4384,17 @@ static inline BOOL shader_constant_is_local(const struct wined3d_shader *shader, return FALSE; }
+static inline BOOL shader_sampler_is_shadow(const struct wined3d_shader *shader, + const struct ps_compile_args *ps_args, unsigned int resource_idx, unsigned int sampler_idx) +{ + const struct wined3d_shader_version *version = &shader->reg_maps.shader_version; + + if (version->major >= 4) + return shader->reg_maps.sampler_comparison_mode & (1u << sampler_idx); + else + return version->type == WINED3D_SHADER_TYPE_PIXEL && (ps_args->shadow & (1u << resource_idx)); +} + void get_identity_matrix(struct wined3d_matrix *mat) DECLSPEC_HIDDEN; void get_modelview_matrix(const struct wined3d_context *context, const struct wined3d_state *state, unsigned int index, struct wined3d_matrix *mat) DECLSPEC_HIDDEN;