wined3d: Keep track of enabled clip distances.

Signed-off-by: Józef Kucia <jkucia@codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Józef Kucia 2017-12-02 10:24:43 +01:00 committed by Alexandre Julliard
parent cf0f523243
commit 46cf12318b
3 changed files with 40 additions and 42 deletions

View file

@ -2352,6 +2352,33 @@ static void context_get_rt_size(const struct wined3d_context *context, SIZE *siz
size->cy = wined3d_texture_get_level_height(rt, level);
}
void context_enable_clip_distances(struct wined3d_context *context, unsigned int enable_mask)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
unsigned int clip_distance_count = gl_info->limits.user_clip_distances;
unsigned int i, disable_mask, current_mask;
disable_mask = ~enable_mask;
enable_mask &= (1u << clip_distance_count) - 1;
disable_mask &= (1u << clip_distance_count) - 1;
current_mask = context->clip_distance_mask;
context->clip_distance_mask = enable_mask;
enable_mask &= ~current_mask;
for (i = 0; enable_mask; enable_mask >>= 1, ++i)
{
if (enable_mask & 1)
gl_info->gl_ops.gl.p_glEnable(GL_CLIP_DISTANCE0 + i);
}
disable_mask &= current_mask;
for (i = 0; disable_mask; disable_mask >>= 1, ++i)
{
if (disable_mask & 1)
gl_info->gl_ops.gl.p_glDisable(GL_CLIP_DISTANCE0 + i);
}
checkGLcall("toggle clip distances");
}
/*****************************************************************************
* SetupForBlit
*
@ -2530,9 +2557,7 @@ static void SetupForBlit(const struct wined3d_device *device, struct wined3d_con
context->last_was_rhw = TRUE;
context_invalidate_state(context, STATE_VDECL); /* because of last_was_rhw = TRUE */
for (i = 0; i < gl_info->limits.user_clip_distances; ++i)
gl_info->gl_ops.gl.p_glDisable(GL_CLIP_DISTANCE0 + i);
checkGLcall("disable clip planes");
context_enable_clip_distances(context, 0);
context_invalidate_state(context, STATE_RENDER(WINED3D_RS_CLIPPING));
/* FIXME: Make draw_textured_quad() able to work with a upper left origin. */

View file

@ -611,9 +611,7 @@ void state_alpha_test(struct wined3d_context *context, const struct wined3d_stat
void state_clipping(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
{
const struct wined3d_gl_info *gl_info = context->gl_info;
unsigned int clipplane_count = gl_info->limits.user_clip_distances;
unsigned int i, enable_mask, disable_mask;
unsigned int enable_mask;
if (use_vs(state) && !context->d3d_info->vs_clipping)
{
@ -626,7 +624,7 @@ void state_clipping(struct wined3d_context *context, const struct wined3d_state
* disables all clip planes because of that - don't do anything here
* and keep them disabled. */
if (state->render_states[WINED3D_RS_CLIPPLANEENABLE] && !warned++)
FIXME("Clipping not supported with vertex shaders\n");
FIXME("Clipping not supported with vertex shaders.\n");
return;
}
@ -636,36 +634,12 @@ void state_clipping(struct wined3d_context *context, const struct wined3d_state
* need to update the clipping field from ffp_vertex_settings. */
context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX;
/* TODO: Keep track of previously enabled clipplanes to avoid unnecessary resetting
* of already set values
*/
/* If enabling / disabling all
* TODO: Is this correct? Doesn't D3DRS_CLIPPING disable clipping on the viewport frustrum?
*/
if (state->render_states[WINED3D_RS_CLIPPING])
{
enable_mask = state->render_states[WINED3D_RS_CLIPPLANEENABLE];
disable_mask = ~state->render_states[WINED3D_RS_CLIPPLANEENABLE];
}
else
{
enable_mask = 0;
disable_mask = ~0u;
}
enable_mask &= (1u << clipplane_count) - 1;
disable_mask &= (1u << clipplane_count) - 1;
for (i = 0; enable_mask && i < clipplane_count; enable_mask >>= 1, ++i)
if (enable_mask & 1)
gl_info->gl_ops.gl.p_glEnable(GL_CLIP_DISTANCE0 + i);
checkGLcall("clip plane enable");
for (i = 0; disable_mask && i < clipplane_count; disable_mask >>= 1, ++i)
if (disable_mask & 1)
gl_info->gl_ops.gl.p_glDisable(GL_CLIP_DISTANCE0 + i);
checkGLcall("clip plane disable");
enable_mask = state->render_states[WINED3D_RS_CLIPPING] ?
state->render_states[WINED3D_RS_CLIPPLANEENABLE] : 0;
context_enable_clip_distances(context, enable_mask);
}
static void state_specularenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id)
@ -4532,22 +4506,19 @@ static void vertexdeclaration(struct wined3d_context *context, const struct wine
}
else
{
if(!context->last_was_vshader) {
if (!context->last_was_vshader)
{
static BOOL warned = FALSE;
if (!context->d3d_info->vs_clipping)
{
/* Disable all clip planes to get defined results on all drivers. See comment in the
* state_clipping state handler
*/
for (i = 0; i < gl_info->limits.user_clip_distances; ++i)
{
gl_info->gl_ops.gl.p_glDisable(GL_CLIP_PLANE0 + i);
checkGLcall("glDisable(GL_CLIP_PLANE0 + i)");
}
context_enable_clip_distances(context, 0);
if (!warned && state->render_states[WINED3D_RS_CLIPPLANEENABLE])
{
FIXME("Clipping not supported with vertex shaders\n");
FIXME("Clipping not supported with vertex shaders.\n");
warned = TRUE;
}
}

View file

@ -1901,7 +1901,8 @@ struct wined3d_context
DWORD transform_feedback_active : 1;
DWORD transform_feedback_paused : 1;
DWORD shader_update_mask : 6; /* WINED3D_SHADER_TYPE_COUNT, 6 */
DWORD padding : 17;
DWORD clip_distance_mask : 8; /* MAX_CLIP_DISTANCES, 8 */
DWORD padding : 9;
DWORD constant_update_mask;
DWORD numbered_array_mask;
GLenum tracking_parm; /* Which source is tracking current colour */
@ -2146,6 +2147,7 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, stru
const struct wined3d_format *ds_format) DECLSPEC_HIDDEN;
HGLRC context_create_wgl_attribs(const struct wined3d_gl_info *gl_info, HDC hdc, HGLRC share_ctx) DECLSPEC_HIDDEN;
void context_destroy(struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN;
void context_enable_clip_distances(struct wined3d_context *context, unsigned int mask) DECLSPEC_HIDDEN;
void context_end_transform_feedback(struct wined3d_context *context) DECLSPEC_HIDDEN;
void context_free_fence(struct wined3d_fence *fence) DECLSPEC_HIDDEN;
void context_free_occlusion_query(struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN;