Commit 52795554 authored by Matteo Bruni's avatar Matteo Bruni Committed by Alexandre Julliard

wined3d: Implement shadow sampling for the ARB shader backend.

parent 1eba5fd9
...@@ -84,6 +84,7 @@ static const struct wined3d_extension_map gl_extension_map[] = ...@@ -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_coord_conventions", ARB_FRAGMENT_COORD_CONVENTIONS},
{"GL_ARB_fragment_layer_viewport", ARB_FRAGMENT_LAYER_VIEWPORT }, {"GL_ARB_fragment_layer_viewport", ARB_FRAGMENT_LAYER_VIEWPORT },
{"GL_ARB_fragment_program", ARB_FRAGMENT_PROGRAM }, {"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_fragment_shader", ARB_FRAGMENT_SHADER },
{"GL_ARB_framebuffer_no_attachments", ARB_FRAMEBUFFER_NO_ATTACHMENTS}, {"GL_ARB_framebuffer_no_attachments", ARB_FRAMEBUFFER_NO_ATTACHMENTS},
{"GL_ARB_framebuffer_object", ARB_FRAMEBUFFER_OBJECT }, {"GL_ARB_framebuffer_object", ARB_FRAMEBUFFER_OBJECT },
......
...@@ -1426,6 +1426,7 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, unsig ...@@ -1426,6 +1426,7 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, unsig
enum wined3d_shader_resource_type resource_type; enum wined3d_shader_resource_type resource_type;
struct color_fixup_masks masks; struct color_fixup_masks masks;
const char *tex_dst = dst_str; const char *tex_dst = dst_str;
bool shadow_sampler, tex_rect;
BOOL np2_fixup = FALSE; BOOL np2_fixup = FALSE;
const char *tex_type; const char *tex_type;
const char *mod; const char *mod;
...@@ -1443,18 +1444,35 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, unsig ...@@ -1443,18 +1444,35 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, unsig
sampler_idx += WINED3D_MAX_FRAGMENT_SAMPLERS; 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) switch (resource_type)
{ {
case WINED3D_SHADER_RESOURCE_TEXTURE_1D: case WINED3D_SHADER_RESOURCE_TEXTURE_1D:
if (shadow_sampler)
tex_type = "SHADOW1D";
else
tex_type = "1D"; tex_type = "1D";
break; break;
case WINED3D_SHADER_RESOURCE_TEXTURE_2D: case WINED3D_SHADER_RESOURCE_TEXTURE_2D:
if (pshader && priv->cur_ps_args->super.np2_fixup & (1u << sampler_idx) tex_rect = pshader && priv->cur_ps_args->super.np2_fixup & (1u << sampler_idx)
&& priv->gl_info->supported[ARB_TEXTURE_RECTANGLE]) && priv->gl_info->supported[ARB_TEXTURE_RECTANGLE];
if (shadow_sampler)
{
if (tex_rect)
tex_type = "SHADOWRECT";
else
tex_type = "SHADOW2D";
}
else
{
if (tex_rect)
tex_type = "RECT"; tex_type = "RECT";
else else
tex_type = "2D"; tex_type = "2D";
}
if (pshader) if (pshader)
{ {
...@@ -1467,10 +1485,14 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, unsig ...@@ -1467,10 +1485,14 @@ static void shader_hw_sample(const struct wined3d_shader_instruction *ins, unsig
break; break;
case WINED3D_SHADER_RESOURCE_TEXTURE_3D: case WINED3D_SHADER_RESOURCE_TEXTURE_3D:
if (shadow_sampler)
FIXME("Unsupported 3D shadow sampler.\n");
tex_type = "3D"; tex_type = "3D";
break; break;
case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE: case WINED3D_SHADER_RESOURCE_TEXTURE_CUBE:
if (shadow_sampler)
FIXME("Unsupported cube shadow sampler.\n");
tex_type = "CUBE"; tex_type = "CUBE";
break; break;
...@@ -3656,6 +3678,8 @@ static GLuint shader_arb_generate_pshader(const struct wined3d_shader *shader, ...@@ -3656,6 +3678,8 @@ static GLuint shader_arb_generate_pshader(const struct wined3d_shader *shader,
break; 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 /* 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 * unused temps away(but occupies them for the whole shader if they're used once). Always
......
...@@ -2110,17 +2110,6 @@ static BOOL glsl_is_color_reg_read(const struct wined3d_shader *shader, unsigned ...@@ -2110,17 +2110,6 @@ static BOOL glsl_is_color_reg_read(const struct wined3d_shader *shader, unsigned
return FALSE; 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, 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, const struct wined3d_gl_info *gl_info, const char *vector_type, const char *scalar_type,
unsigned int index) unsigned int index)
...@@ -2345,7 +2334,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context_gl *c ...@@ -2345,7 +2334,7 @@ static void shader_generate_glsl_declarations(const struct wined3d_context_gl *c
break; 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 resource_type = version->type == WINED3D_SHADER_TYPE_PIXEL
? pixelshader_get_resource_type(reg_maps, entry->resource_idx, ps_args->tex_types) ? pixelshader_get_resource_type(reg_maps, entry->resource_idx, ps_args->tex_types)
: reg_maps->resource_info[entry->resource_idx].type; : reg_maps->resource_info[entry->resource_idx].type;
...@@ -3424,7 +3413,7 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context ...@@ -3424,7 +3413,7 @@ static void shader_glsl_get_sample_function(const struct wined3d_shader_context
enum wined3d_shader_resource_type resource_type; enum wined3d_shader_resource_type resource_type;
struct shader_glsl_ctx_priv *priv = ctx->backend_data; struct shader_glsl_ctx_priv *priv = ctx->backend_data;
const struct wined3d_gl_info *gl_info = priv->gl_info; 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 projected = flags & WINED3D_GLSL_SAMPLE_PROJECTED;
BOOL texrect = ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL BOOL texrect = ctx->reg_maps->shader_version.type == WINED3D_SHADER_TYPE_PIXEL
&& priv->cur_ps_args->np2_fixup & (1u << resource_idx) && priv->cur_ps_args->np2_fixup & (1u << resource_idx)
......
...@@ -78,6 +78,7 @@ enum wined3d_gl_extension ...@@ -78,6 +78,7 @@ enum wined3d_gl_extension
ARB_FRAGMENT_COORD_CONVENTIONS, ARB_FRAGMENT_COORD_CONVENTIONS,
ARB_FRAGMENT_LAYER_VIEWPORT, ARB_FRAGMENT_LAYER_VIEWPORT,
ARB_FRAGMENT_PROGRAM, ARB_FRAGMENT_PROGRAM,
ARB_FRAGMENT_PROGRAM_SHADOW,
ARB_FRAGMENT_SHADER, ARB_FRAGMENT_SHADER,
ARB_FRAMEBUFFER_NO_ATTACHMENTS, ARB_FRAMEBUFFER_NO_ATTACHMENTS,
ARB_FRAMEBUFFER_OBJECT, ARB_FRAMEBUFFER_OBJECT,
......
...@@ -4384,6 +4384,17 @@ static inline BOOL shader_constant_is_local(const struct wined3d_shader *shader, ...@@ -4384,6 +4384,17 @@ static inline BOOL shader_constant_is_local(const struct wined3d_shader *shader,
return FALSE; 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_identity_matrix(struct wined3d_matrix *mat) DECLSPEC_HIDDEN;
void get_modelview_matrix(const struct wined3d_context *context, const struct wined3d_state *state, void get_modelview_matrix(const struct wined3d_context *context, const struct wined3d_state *state,
unsigned int index, struct wined3d_matrix *mat) DECLSPEC_HIDDEN; unsigned int index, struct wined3d_matrix *mat) DECLSPEC_HIDDEN;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment