From 5650d3997851007a4e4268a4fa4bd698db41e7dc Mon Sep 17 00:00:00 2001 From: Sagar Ghuge Date: Fri, 27 Jul 2018 14:55:57 -0700 Subject: [PATCH] mesa: Add support for AMD_depth_clamp_separate MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Enable _mesa_PushAttrib() and _mesa_PopAttrib() to handle GL_DEPTH_CLAMP_NEAR_AMD and GL_DEPTH_CLAMP_FAR_AMD tokens. Remove DepthClamp, because DepthClampNear + DepthClampFar replaces it, as suggested by Marek Olsak. Driver that enables AMD_depth_clamp_separate will only ever look at DepthClampNear and DepthClampFar, as suggested by Ian Romanick. v2: 1) Remove unnecessary parentheses (Marek Olsak) 2) if AMD_depth_clamp_separate is unsupported, TEST_AND_UPDATE GL_DEPTH_CLAMP only (Marek Olsak) 3) Clamp against near and far plane separately (Marek Olsak) 4) Clip point separately for near and far Z clipping plane (Marek Olsak) v3: Clamp raster position zw to the range [min(n,f), 0] for near plane and [0, max(n,f)] for far plane (Marek Olsak) v4: Use MIN2 and MAX2 instead of CLAMP (Marek Olsak) Signed-off-by: Sagar Ghuge Reviewed-by: Ian Romanick Reviewed-by: Marek Olšák --- src/mesa/drivers/dri/i965/genX_state_upload.c | 11 ++++-- src/mesa/main/attrib.c | 40 +++++++++++++++---- src/mesa/main/enable.c | 9 +++-- src/mesa/main/get.c | 4 ++ src/mesa/main/get_hash_params.py | 2 +- src/mesa/main/mtypes.h | 1 - src/mesa/main/rastpos.c | 55 ++++++++++++++++++++++----- src/mesa/state_tracker/st_atom_rasterizer.c | 3 +- src/mesa/state_tracker/st_cb_drawpixels.c | 3 +- src/mesa/swrast/s_span.c | 2 +- src/mesa/tnl/t_vb_program.c | 6 ++- src/mesa/tnl/t_vb_vertex.c | 8 ++-- 12 files changed, 111 insertions(+), 33 deletions(-) diff --git a/src/mesa/drivers/dri/i965/genX_state_upload.c b/src/mesa/drivers/dri/i965/genX_state_upload.c index ca24394..24977a7 100644 --- a/src/mesa/drivers/dri/i965/genX_state_upload.c +++ b/src/mesa/drivers/dri/i965/genX_state_upload.c @@ -1399,7 +1399,8 @@ genX(upload_clip_state)(struct brw_context *brw) clip.ScreenSpaceViewportYMax = 1; clip.ViewportXYClipTestEnable = true; - clip.ViewportZClipTestEnable = !ctx->Transform.DepthClamp; + clip.ViewportZClipTestEnable = !(ctx->Transform.DepthClampNear && + ctx->Transform.DepthClampFar); /* _NEW_TRANSFORM */ if (GEN_GEN == 5 || GEN_IS_G4X) { @@ -1493,7 +1494,8 @@ genX(upload_clip_state)(struct brw_context *brw) clip.UserClipDistanceCullTestEnableBitmask = brw_vue_prog_data(brw->vs.base.prog_data)->cull_distance_mask; - clip.ViewportZClipTestEnable = !ctx->Transform.DepthClamp; + clip.ViewportZClipTestEnable = !(ctx->Transform.DepthClampNear && + ctx->Transform.DepthClampFar); #endif /* _NEW_LIGHT */ @@ -2338,7 +2340,7 @@ genX(upload_cc_viewport)(struct brw_context *brw) for (unsigned i = 0; i < viewport_count; i++) { /* _NEW_VIEWPORT | _NEW_TRANSFORM */ const struct gl_viewport_attrib *vp = &ctx->ViewportArray[i]; - if (ctx->Transform.DepthClamp) { + if (ctx->Transform.DepthClampNear && ctx->Transform.DepthClampFar) { ccv.MinimumDepth = MIN2(vp->Near, vp->Far); ccv.MaximumDepth = MAX2(vp->Near, vp->Far); } else { @@ -4605,7 +4607,8 @@ genX(upload_raster)(struct brw_context *brw) raster.ScissorRectangleEnable = ctx->Scissor.EnableFlags; /* _NEW_TRANSFORM */ - if (!ctx->Transform.DepthClamp) { + if (!(ctx->Transform.DepthClampNear && + ctx->Transform.DepthClampFar)) { #if GEN_GEN >= 9 raster.ViewportZFarClipTestEnable = true; raster.ViewportZNearClipTestEnable = true; diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index cbe93ab..a46fec7 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -72,7 +72,8 @@ struct gl_enable_attrib GLbitfield ClipPlanes; GLboolean ColorMaterial; GLboolean CullFace; - GLboolean DepthClamp; + GLboolean DepthClampNear; + GLboolean DepthClampFar; GLboolean DepthTest; GLboolean Dither; GLboolean Fog; @@ -336,7 +337,8 @@ _mesa_PushAttrib(GLbitfield mask) attr->ClipPlanes = ctx->Transform.ClipPlanesEnabled; attr->ColorMaterial = ctx->Light.ColorMaterialEnabled; attr->CullFace = ctx->Polygon.CullFlag; - attr->DepthClamp = ctx->Transform.DepthClamp; + attr->DepthClampNear = ctx->Transform.DepthClampNear; + attr->DepthClampFar = ctx->Transform.DepthClampFar; attr->DepthTest = ctx->Depth.Test; attr->Dither = ctx->Color.DitherFlag; attr->Fog = ctx->Fog.Enabled; @@ -627,8 +629,18 @@ pop_enable_group(struct gl_context *ctx, const struct gl_enable_attrib *enable) TEST_AND_UPDATE(ctx->Light.ColorMaterialEnabled, enable->ColorMaterial, GL_COLOR_MATERIAL); TEST_AND_UPDATE(ctx->Polygon.CullFlag, enable->CullFace, GL_CULL_FACE); - TEST_AND_UPDATE(ctx->Transform.DepthClamp, enable->DepthClamp, - GL_DEPTH_CLAMP); + + if (!ctx->Extensions.AMD_depth_clamp_separate) { + TEST_AND_UPDATE(ctx->Transform.DepthClampNear && ctx->Transform.DepthClampFar, + enable->DepthClampNear && enable->DepthClampFar, + GL_DEPTH_CLAMP); + } else { + TEST_AND_UPDATE(ctx->Transform.DepthClampNear, enable->DepthClampNear, + GL_DEPTH_CLAMP_NEAR_AMD); + TEST_AND_UPDATE(ctx->Transform.DepthClampFar, enable->DepthClampFar, + GL_DEPTH_CLAMP_FAR_AMD); + } + TEST_AND_UPDATE(ctx->Depth.Test, enable->DepthTest, GL_DEPTH_TEST); TEST_AND_UPDATE(ctx->Color.DitherFlag, enable->Dither, GL_DITHER); TEST_AND_UPDATE(ctx->Fog.Enabled, enable->Fog, GL_FOG); @@ -1433,9 +1445,23 @@ _mesa_PopAttrib(void) if (xform->RescaleNormals != ctx->Transform.RescaleNormals) _mesa_set_enable(ctx, GL_RESCALE_NORMAL_EXT, ctx->Transform.RescaleNormals); - if (xform->DepthClamp != ctx->Transform.DepthClamp) - _mesa_set_enable(ctx, GL_DEPTH_CLAMP, - ctx->Transform.DepthClamp); + + if (!ctx->Extensions.AMD_depth_clamp_separate) { + if (xform->DepthClampNear != ctx->Transform.DepthClampNear && + xform->DepthClampFar != ctx->Transform.DepthClampFar) { + _mesa_set_enable(ctx, GL_DEPTH_CLAMP, + ctx->Transform.DepthClampNear && + ctx->Transform.DepthClampFar); + } + } else { + if (xform->DepthClampNear != ctx->Transform.DepthClampNear) + _mesa_set_enable(ctx, GL_DEPTH_CLAMP_NEAR_AMD, + ctx->Transform.DepthClampNear); + if (xform->DepthClampFar != ctx->Transform.DepthClampFar) + _mesa_set_enable(ctx, GL_DEPTH_CLAMP_FAR_AMD, + ctx->Transform.DepthClampFar); + } + if (ctx->Extensions.ARB_clip_control) _mesa_ClipControl(xform->ClipOrigin, xform->ClipDepthMode); } diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c index d1b2f3a..30d2750 100644 --- a/src/mesa/main/enable.c +++ b/src/mesa/main/enable.c @@ -1007,12 +1007,14 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) if (!_mesa_is_desktop_gl(ctx)) goto invalid_enum_error; CHECK_EXTENSION(ARB_depth_clamp, cap); - if (ctx->Transform.DepthClamp == state) + if (ctx->Transform.DepthClampNear == state && + ctx->Transform.DepthClampFar == state) return; FLUSH_VERTICES(ctx, ctx->DriverFlags.NewDepthClamp ? 0 : _NEW_TRANSFORM); ctx->NewDriverState |= ctx->DriverFlags.NewDepthClamp; - ctx->Transform.DepthClamp = state; + ctx->Transform.DepthClampNear = state; + ctx->Transform.DepthClampFar = state; break; case GL_FRAGMENT_SHADER_ATI: @@ -1684,7 +1686,8 @@ _mesa_IsEnabled( GLenum cap ) if (!_mesa_is_desktop_gl(ctx)) goto invalid_enum_error; CHECK_EXTENSION(ARB_depth_clamp); - return ctx->Transform.DepthClamp; + return ctx->Transform.DepthClampNear || + ctx->Transform.DepthClampFar; case GL_FRAGMENT_SHADER_ATI: if (ctx->API != API_OPENGL_COMPAT) diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index f870b21..16625e9 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -698,6 +698,10 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu v->value_int_4[3] = GET_COLORMASK_BIT(ctx->Color.ColorMask, 0, 3); break; + case GL_DEPTH_CLAMP: + v->value_bool = ctx->Transform.DepthClampNear || ctx->Transform.DepthClampFar; + break; + case GL_EDGE_FLAG: v->value_bool = ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0] == 1.0F; break; diff --git a/src/mesa/main/get_hash_params.py b/src/mesa/main/get_hash_params.py index ed5328d..87ed4bf 100644 --- a/src/mesa/main/get_hash_params.py +++ b/src/mesa/main/get_hash_params.py @@ -903,7 +903,7 @@ descriptor=[ [ "DEPTH_BOUNDS_EXT", "CONTEXT_FLOAT2(Depth.BoundsMin), extra_EXT_depth_bounds_test" ], # GL_ARB_depth_clamp - [ "DEPTH_CLAMP", "CONTEXT_BOOL(Transform.DepthClamp), extra_ARB_depth_clamp" ], + [ "DEPTH_CLAMP", "LOC_CUSTOM, TYPE_BOOLEAN, 0, extra_ARB_depth_clamp" ], # GL_ATI_fragment_shader [ "FRAGMENT_SHADER_ATI", "CONTEXT_BOOL(ATIFragmentShader.Enabled), extra_ATI_fragment_shader" ], diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index e752046..5ce0b4b 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1282,7 +1282,6 @@ struct gl_transform_attrib GLboolean Normalize; /**< Normalize all normals? */ GLboolean RescaleNormals; /**< GL_EXT_rescale_normal */ GLboolean RasterPositionUnclipped; /**< GL_IBM_rasterpos_clip */ - GLboolean DepthClamp; /**< GL_ARB_depth_clamp */ GLboolean DepthClampNear; /**< GL_AMD_depth_clamp_separate */ GLboolean DepthClampFar; /**< GL_AMD_depth_clamp_separate */ /** GL_ARB_clip_control */ diff --git a/src/mesa/main/rastpos.c b/src/mesa/main/rastpos.c index 1ca83c7..0308003 100644 --- a/src/mesa/main/rastpos.c +++ b/src/mesa/main/rastpos.c @@ -61,16 +61,35 @@ viewclip_point_xy( const GLfloat v[] ) /** - * Clip a point against the far/near Z clipping planes. + * Clip a point against the near Z clipping planes. * * \param v vertex vector describing the point to clip. * * \return zero if outside view volume, or one if inside. */ static GLuint -viewclip_point_z( const GLfloat v[] ) +viewclip_point_near_z( const GLfloat v[] ) { - if (v[2] > v[3] || v[2] < -v[3] ) { + if (v[2] < -v[3]) { + return 0; + } + else { + return 1; + } +} + + +/** + * Clip a point against the far Z clipping planes. + * + * \param v vertex vector describing the point to clip. + * + * \return zero if outside view volume, or one if inside. + */ +static GLuint +viewclip_point_far_z( const GLfloat v[] ) +{ + if (v[2] > v[3]) { return 0; } else { @@ -389,8 +408,14 @@ _mesa_RasterPos(struct gl_context *ctx, const GLfloat vObj[4]) TRANSFORM_POINT( clip, ctx->ProjectionMatrixStack.Top->m, eye ); /* clip to view volume. */ - if (!ctx->Transform.DepthClamp) { - if (viewclip_point_z(clip) == 0) { + if (!ctx->Transform.DepthClampNear) { + if (viewclip_point_near_z(clip) == 0) { + ctx->Current.RasterPosValid = GL_FALSE; + return; + } + } + if (!ctx->Transform.DepthClampFar) { + if (viewclip_point_far_z(clip) == 0) { ctx->Current.RasterPosValid = GL_FALSE; return; } @@ -420,10 +445,22 @@ _mesa_RasterPos(struct gl_context *ctx, const GLfloat vObj[4]) ctx->Current.RasterPos[2] = ndc[2] * scale[2] + translate[2]; ctx->Current.RasterPos[3] = clip[3]; - if (ctx->Transform.DepthClamp) { - ctx->Current.RasterPos[3] = CLAMP(ctx->Current.RasterPos[3], - ctx->ViewportArray[0].Near, - ctx->ViewportArray[0].Far); + if (ctx->Transform.DepthClampNear && + ctx->Transform.DepthClampFar) { + ctx->Current.RasterPos[3] = CLAMP(ctx->Current.RasterPos[3], + ctx->ViewportArray[0].Near, + ctx->ViewportArray[0].Far); + } else { + /* Clamp against near and far plane separately */ + if (ctx->Transform.DepthClampNear) { + ctx->Current.RasterPos[3] = MAX2(ctx->Current.RasterPos[3], + ctx->ViewportArray[0].Near); + } + + if (ctx->Transform.DepthClampFar) { + ctx->Current.RasterPos[3] = MIN2(ctx->Current.RasterPos[3], + ctx->ViewportArray[0].Far); + } } /* compute raster distance */ diff --git a/src/mesa/state_tracker/st_atom_rasterizer.c b/src/mesa/state_tracker/st_atom_rasterizer.c index 0383b8a..1f66b9d 100644 --- a/src/mesa/state_tracker/st_atom_rasterizer.c +++ b/src/mesa/state_tracker/st_atom_rasterizer.c @@ -294,7 +294,8 @@ st_update_rasterizer(struct st_context *st) } /* _NEW_TRANSFORM */ - raster->depth_clip = !ctx->Transform.DepthClamp; + raster->depth_clip = !(ctx->Transform.DepthClampNear && + ctx->Transform.DepthClampFar); raster->clip_plane_enable = ctx->Transform.ClipPlanesEnabled; raster->clip_halfz = (ctx->Transform.ClipDepthMode == GL_ZERO_TO_ONE); diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index b889568..67bbb35 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -677,7 +677,8 @@ draw_textured_quad(struct gl_context *ctx, GLint x, GLint y, GLfloat z, ctx->Color._ClampFragmentColor; rasterizer.half_pixel_center = 1; rasterizer.bottom_edge_rule = 1; - rasterizer.depth_clip = !ctx->Transform.DepthClamp; + rasterizer.depth_clip = !(ctx->Transform.DepthClampNear && + ctx->Transform.DepthClampFar); rasterizer.scissor = ctx->Scissor.EnableFlags; cso_set_rasterizer(cso, &rasterizer); } diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index 87b72e8..f50b549 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -1219,7 +1219,7 @@ _swrast_write_rgba_span( struct gl_context *ctx, SWspan *span) if (!(span->arrayMask & SPAN_Z)) _swrast_span_interpolate_z(ctx, span); - if (ctx->Transform.DepthClamp) + if (ctx->Transform.DepthClampNear && ctx->Transform.DepthClampFar) _swrast_depth_clamp_span(ctx, span); if (_mesa_stencil_is_enabled(ctx)) { diff --git a/src/mesa/tnl/t_vb_program.c b/src/mesa/tnl/t_vb_program.c index 19be5ee..8d8aca6 100644 --- a/src/mesa/tnl/t_vb_program.c +++ b/src/mesa/tnl/t_vb_program.c @@ -143,7 +143,8 @@ do_ndc_cliptest(struct gl_context *ctx, struct vp_stage_data *store) store->clipmask, &store->ormask, &store->andmask, - !ctx->Transform.DepthClamp ); + !(ctx->Transform.DepthClampNear && + ctx->Transform.DepthClampFar) ); } else { VB->NdcPtr = NULL; @@ -152,7 +153,8 @@ do_ndc_cliptest(struct gl_context *ctx, struct vp_stage_data *store) store->clipmask, &store->ormask, &store->andmask, - !ctx->Transform.DepthClamp ); + !(ctx->Transform.DepthClampNear && + ctx->Transform.DepthClampFar) ); } if (store->andmask) { diff --git a/src/mesa/tnl/t_vb_vertex.c b/src/mesa/tnl/t_vb_vertex.c index 71a32b4..4fb3659 100644 --- a/src/mesa/tnl/t_vb_vertex.c +++ b/src/mesa/tnl/t_vb_vertex.c @@ -123,7 +123,7 @@ tnl_clip_prepare(struct gl_context *ctx) /* Neither the x86 nor sparc asm cliptest functions have been updated * for ARB_depth_clamp, so force the C paths. */ - if (ctx->Transform.DepthClamp) { + if (ctx->Transform.DepthClampNear && ctx->Transform.DepthClampFar) { static GLboolean c_funcs_installed = GL_FALSE; if (!c_funcs_installed) { init_c_cliptest(); @@ -191,7 +191,8 @@ static GLboolean run_vertex_stage( struct gl_context *ctx, store->clipmask, &store->ormask, &store->andmask, - !ctx->Transform.DepthClamp ); + !(ctx->Transform.DepthClampNear && + ctx->Transform.DepthClampFar) ); } else { VB->NdcPtr = NULL; @@ -200,7 +201,8 @@ static GLboolean run_vertex_stage( struct gl_context *ctx, store->clipmask, &store->ormask, &store->andmask, - !ctx->Transform.DepthClamp ); + !(ctx->Transform.DepthClampNear && + ctx->Transform.DepthClampFar) ); } if (store->andmask) -- 2.7.4