-- v2: wined3d: Don't skip setting clip planes if the view transform state is dirty. wined3d: Implement shadow sampling for the ARB shader backend. wined3d: Allow FFP blits to non-render targets with the 'none' shader backend. wined3d: Handle NULL push constant buffers with the ARB shader backend. wined3d: Fix handling of system-memory GL vertex buffers.
From: Matteo Bruni mbruni@codeweavers.com
Fixes: c065b4fe0b3622e0c737a4c7c1c514273ad2d8a7 --- dlls/wined3d/context_gl.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c index a55365cdf12..b81f14a86ee 100644 --- a/dlls/wined3d/context_gl.c +++ b/dlls/wined3d/context_gl.c @@ -5399,7 +5399,8 @@ void wined3d_context_gl_load_tex_coords(const struct wined3d_context_gl *context gl_info->gl_ops.gl.p_glTexCoordPointer(format_gl->vtx_format, format_gl->vtx_type, e->stride, get_vertex_attrib_pointer(e, state)); gl_info->gl_ops.gl.p_glEnableClientState(GL_TEXTURE_COORD_ARRAY); - wined3d_buffer_validate_user(state->streams[e->stream_idx].buffer); + if (bo) + wined3d_buffer_validate_user(state->streams[e->stream_idx].buffer); } else { @@ -5486,7 +5487,8 @@ static void wined3d_context_gl_load_vertex_data(struct wined3d_context_gl *conte checkGLcall("glVertexPointer(...)"); gl_info->gl_ops.gl.p_glEnableClientState(GL_VERTEX_ARRAY); checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)"); - wined3d_buffer_validate_user(state->streams[e->stream_idx].buffer); + if (bo) + wined3d_buffer_validate_user(state->streams[e->stream_idx].buffer); }
/* Normals */ @@ -5509,7 +5511,8 @@ static void wined3d_context_gl_load_vertex_data(struct wined3d_context_gl *conte checkGLcall("glNormalPointer(...)"); gl_info->gl_ops.gl.p_glEnableClientState(GL_NORMAL_ARRAY); checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)"); - wined3d_buffer_validate_user(state->streams[e->stream_idx].buffer); + if (bo) + wined3d_buffer_validate_user(state->streams[e->stream_idx].buffer); } else { @@ -5538,7 +5541,8 @@ static void wined3d_context_gl_load_vertex_data(struct wined3d_context_gl *conte checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)"); gl_info->gl_ops.gl.p_glEnableClientState(GL_COLOR_ARRAY); checkGLcall("glEnableClientState(GL_COLOR_ARRAY)"); - wined3d_buffer_validate_user(state->streams[e->stream_idx].buffer); + if (bo) + wined3d_buffer_validate_user(state->streams[e->stream_idx].buffer); } else { @@ -5602,7 +5606,8 @@ static void wined3d_context_gl_load_vertex_data(struct wined3d_context_gl *conte } gl_info->gl_ops.gl.p_glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT); checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)"); - wined3d_buffer_validate_user(state->streams[e->stream_idx].buffer); + if (bo) + wined3d_buffer_validate_user(state->streams[e->stream_idx].buffer); } else { @@ -5703,8 +5708,6 @@ static void wined3d_context_gl_load_numbered_arrays(struct wined3d_context_gl *c
format_gl = wined3d_format_gl(element->format); stream = &state->streams[element->stream_idx]; - wined3d_buffer_validate_user(stream->buffer); -
if (gl_info->supported[ARB_INSTANCED_ARRAYS]) { @@ -5738,6 +5741,9 @@ static void wined3d_context_gl_load_numbered_arrays(struct wined3d_context_gl *c checkGLcall("glBindBuffer"); current_bo = bo; } + if (bo) + wined3d_buffer_validate_user(stream->buffer); + /* Use the VBO to find out if a vertex buffer exists, not the vb * pointer. vb can point to a user pointer data blob. In that case * current_bo will be 0. If there is a vertex buffer but no vbo we
From: Matteo Bruni mbruni@codeweavers.com
Fixes: c065b4fe0b3622e0c737a4c7c1c514273ad2d8a7 --- dlls/wined3d/arb_program_shader.c | 66 +++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 20 deletions(-)
diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 272a25902d9..c2eeadfdcbe 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -517,6 +517,13 @@ static void shader_arb_load_np2fixup_constants(const struct arb_ps_np2fixup_info } }
+static void *shader_arb_get_push_constants_sysmem(struct wined3d_buffer *buffer, struct wined3d_context *context) +{ + if (!buffer) + return NULL; + return wined3d_buffer_load_sysmem(buffer, context); +} + /* Context activation is done by the caller. */ static void shader_arb_ps_local_constants(const struct arb_ps_compiled_shader *gl_shader, struct wined3d_context_gl *context_gl, const struct wined3d_state *state, unsigned int rt_height) @@ -526,7 +533,8 @@ static void shader_arb_ps_local_constants(const struct arb_ps_compiled_shader *g const struct wined3d_ivec4 *int_consts; unsigned char i;
- int_consts = wined3d_buffer_load_sysmem(device->push_constants[WINED3D_PUSH_CONSTANTS_PS_I], &context_gl->c); + int_consts = shader_arb_get_push_constants_sysmem(device->push_constants[WINED3D_PUSH_CONSTANTS_PS_I], + &context_gl->c);
for(i = 0; i < gl_shader->numbumpenvmatconsts; i++) { @@ -601,7 +609,8 @@ static void shader_arb_vs_local_constants(const struct arb_vs_compiled_shader *g
if (!gl_shader->num_int_consts) return;
- int_consts = wined3d_buffer_load_sysmem(device->push_constants[WINED3D_PUSH_CONSTANTS_VS_I], &context_gl->c); + int_consts = shader_arb_get_push_constants_sysmem(device->push_constants[WINED3D_PUSH_CONSTANTS_VS_I], + &context_gl->c);
for (i = 0; i < WINED3D_MAX_CONSTS_I; ++i) { @@ -676,12 +685,16 @@ static void shader_arb_load_constants_internal(struct shader_arb_priv *priv, str { const struct wined3d_shader *vshader = state->shader[WINED3D_SHADER_TYPE_VERTEX]; const struct arb_vs_compiled_shader *gl_shader = priv->compiled_vprog; + void *constants;
/* Load DirectX 9 float constants for vertex shader */ - priv->highest_dirty_vs_const = shader_arb_load_constants_f(vshader, - gl_info, GL_VERTEX_PROGRAM_ARB, priv->highest_dirty_vs_const, - wined3d_buffer_load_sysmem(device->push_constants[WINED3D_PUSH_CONSTANTS_VS_F], &context_gl->c), - priv->vshader_const_dirty); + if ((constants = shader_arb_get_push_constants_sysmem(device->push_constants[WINED3D_PUSH_CONSTANTS_VS_F], + &context_gl->c))) + { + priv->highest_dirty_vs_const = shader_arb_load_constants_f(vshader, + gl_info, GL_VERTEX_PROGRAM_ARB, priv->highest_dirty_vs_const, + constants, priv->vshader_const_dirty); + } shader_arb_vs_local_constants(gl_shader, context_gl, state); }
@@ -690,12 +703,16 @@ static void shader_arb_load_constants_internal(struct shader_arb_priv *priv, str const struct wined3d_shader *pshader = state->shader[WINED3D_SHADER_TYPE_PIXEL]; const struct arb_ps_compiled_shader *gl_shader = priv->compiled_fprog; UINT rt_height = state->fb.render_targets[0]->height; + void *constants;
/* Load DirectX 9 float constants for pixel shader */ - priv->highest_dirty_ps_const = shader_arb_load_constants_f(pshader, - gl_info, GL_FRAGMENT_PROGRAM_ARB, priv->highest_dirty_ps_const, - wined3d_buffer_load_sysmem(device->push_constants[WINED3D_PUSH_CONSTANTS_PS_F], &context_gl->c), - priv->pshader_const_dirty); + if ((constants = shader_arb_get_push_constants_sysmem(device->push_constants[WINED3D_PUSH_CONSTANTS_PS_F], + &context_gl->c))) + { + priv->highest_dirty_ps_const = shader_arb_load_constants_f(pshader, + gl_info, GL_FRAGMENT_PROGRAM_ARB, priv->highest_dirty_ps_const, + constants, priv->pshader_const_dirty); + } shader_arb_ps_local_constants(gl_shader, context_gl, state, rt_height);
if (context_gl->c.constant_update_mask & WINED3D_SHADER_CONST_PS_NP2_FIXUP) @@ -4430,21 +4447,25 @@ static void find_arb_ps_compile_args(const struct wined3d_state *state, struct wined3d_device *device = context_gl->c.device; const struct wined3d_ivec4 *int_consts; const BOOL *bool_consts; - int i; + unsigned int bool_used; WORD int_skip; + int i;
- bool_consts = wined3d_buffer_load_sysmem(device->push_constants[WINED3D_PUSH_CONSTANTS_PS_B], &context_gl->c); - int_consts = wined3d_buffer_load_sysmem(device->push_constants[WINED3D_PUSH_CONSTANTS_PS_I], &context_gl->c); + bool_consts = shader_arb_get_push_constants_sysmem(device->push_constants[WINED3D_PUSH_CONSTANTS_PS_B], + &context_gl->c); + int_consts = shader_arb_get_push_constants_sysmem(device->push_constants[WINED3D_PUSH_CONSTANTS_PS_I], + &context_gl->c);
find_ps_compile_args(state, shader, context_gl->c.stream_info.position_transformed, &args->super, &context_gl->c);
/* This forces all local boolean constants to 1 to make them stateblock independent */ args->bools = shader->reg_maps.local_bool_consts; - - for (i = 0; i < WINED3D_MAX_CONSTS_B; ++i) + bool_used = shader->reg_maps.boolean_constants & ~shader->reg_maps.local_bool_consts; + while (bool_used) { + i = wined3d_bit_scan(&bool_used); if (bool_consts[i]) - args->bools |= ( 1u << i); + args->bools |= 1u << i; }
/* Only enable the clip plane emulation KIL if at least one clipplane is enabled. The KIL instruction @@ -4493,11 +4514,14 @@ static void find_arb_vs_compile_args(const struct wined3d_state *state, const struct wined3d_adapter *adapter = device->adapter; const struct wined3d_ivec4 *int_consts; const BOOL *bool_consts; - int i; + unsigned int bool_used; WORD int_skip; + int i;
- bool_consts = wined3d_buffer_load_sysmem(device->push_constants[WINED3D_PUSH_CONSTANTS_VS_B], &context_gl->c); - int_consts = wined3d_buffer_load_sysmem(device->push_constants[WINED3D_PUSH_CONSTANTS_VS_I], &context_gl->c); + bool_consts = shader_arb_get_push_constants_sysmem(device->push_constants[WINED3D_PUSH_CONSTANTS_VS_B], + &context_gl->c); + int_consts = shader_arb_get_push_constants_sysmem(device->push_constants[WINED3D_PUSH_CONSTANTS_VS_I], + &context_gl->c);
find_vs_compile_args(state, shader, &args->super, &context_gl->c);
@@ -4532,8 +4556,10 @@ static void find_arb_vs_compile_args(const struct wined3d_state *state,
/* This forces all local boolean constants to 1 to make them stateblock independent */ args->clip.boolclip.bools = shader->reg_maps.local_bool_consts; - for (i = 0; i < WINED3D_MAX_CONSTS_B; ++i) + bool_used = shader->reg_maps.boolean_constants & ~shader->reg_maps.local_bool_consts; + while (bool_used) { + i = wined3d_bit_scan(&bool_used); if (bool_consts[i]) args->clip.boolclip.bools |= (1u << i); }
From: Matteo Bruni mbruni@codeweavers.com
In the same vein as 6247bee483b31b1ea0ad49f85f1cffde7433fed2; avoids infinite recursion in the blitter. Triggered by the ddraw tests. --- dlls/wined3d/texture.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 08e95db10f5..a7fbde0f529 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -5832,8 +5832,17 @@ static bool ffp_blit_supported(enum wined3d_blit_op blit_op, const struct wined3
if (!(dst_resource->bind_flags & WINED3D_BIND_RENDER_TARGET)) { - TRACE("Can only blit to render targets.\n"); - return false; + if (dst_format->id == src_format->id && dst_location == WINED3D_LOCATION_DRAWABLE) + { + if (context->device->shader_backend == &none_shader_backend) + WARN("Claiming !render_target support because of no shader backend.\n"); + return true; + } + else + { + TRACE("Can only blit to render targets.\n"); + return false; + } } return true;
From: Matteo Bruni mbruni@codeweavers.com
--- I swear this patch wrote itself... --- 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 0b72bf298e2..3669f64ab81 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4381,6 +4381,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;
From: Matteo Bruni mbruni@codeweavers.com
More fallout from 2ddb6b66a7cda0bf6aaddc0c6899e35cc92ceee9. --- dlls/wined3d/state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 6eaec9acb55..30b0adaa135 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -3680,7 +3680,7 @@ void clipplane(struct wined3d_context *context, const struct wined3d_state *stat UINT index = state_id - STATE_CLIPPLANE(0); GLdouble plane[4];
- if (isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_VIEW)) || index >= gl_info->limits.user_clip_distances) + if (index >= gl_info->limits.user_clip_distances) return;
gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW);
This merge request was approved by Zebediah Figura.
This merge request was approved by Jan Sikorski.